Commit be1b9827cdf668446f4bd876a1b7120fd2f29283

Authored by chwork
2 parents d2ff4271 25b987be

Merge branch 'fix-main-ch' into 'main'

Fix main ch



See merge request !15
Showing 25 changed files with 1550 additions and 109 deletions
src/main/java/com/order/erp/common/utils/EasyPdfUtils.java 0 → 100644
  1 +package com.order.erp.common.utils;
  2 +
  3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4 +import com.order.erp.common.constant.Constant;
  5 +import com.order.erp.common.exception.BusinessException;
  6 +import com.order.erp.domain.dto.BaseDO;
  7 +import com.order.erp.domain.dto.order.OrderBaseInfoDO;
  8 +import com.order.erp.domain.dto.order.OrderProfitAnalysisDO;
  9 +import com.order.erp.domain.pdf.OrderProducePdfVO;
  10 +import com.order.erp.domain.vo.FileRespVO;
  11 +import com.order.erp.domain.vo.ProducePdfVO;
  12 +import com.order.erp.service.LocalStorageService;
  13 +import com.order.erp.service.order.OrderBaseInfoService;
  14 +import com.order.erp.service.order.OrderProfitAnalysisService;
  15 +import lombok.extern.slf4j.Slf4j;
  16 +import org.springframework.beans.BeanUtils;
  17 +import org.springframework.beans.factory.annotation.Value;
  18 +import org.springframework.stereotype.Service;
  19 +import wiki.xsx.core.pdf.component.image.XEasyPdfImage;
  20 +import wiki.xsx.core.pdf.component.image.XEasyPdfImageType;
  21 +import wiki.xsx.core.pdf.component.table.XEasyPdfCell;
  22 +import wiki.xsx.core.pdf.component.table.XEasyPdfRow;
  23 +import wiki.xsx.core.pdf.component.table.XEasyPdfTable;
  24 +import wiki.xsx.core.pdf.doc.*;
  25 +import wiki.xsx.core.pdf.handler.XEasyPdfHandler;
  26 +
  27 +import javax.annotation.Resource;
  28 +import java.awt.*;
  29 +import java.io.File;
  30 +import java.io.IOException;
  31 +import java.io.InputStream;
  32 +import java.io.OutputStream;
  33 +import java.math.BigDecimal;
  34 +import java.math.RoundingMode;
  35 +import java.net.URL;
  36 +import java.util.*;
  37 +import java.util.List;
  38 +import java.util.function.Function;
  39 +import java.util.stream.Collectors;
  40 +//待拷贝start。
  41 +
  42 +/**
  43 + * @author: xms
  44 + * @description: TODO
  45 + * @date: 2024/7/17 16:30
  46 + * @version: 1.0
  47 + */
  48 +@Slf4j
  49 +@Service
  50 +public class EasyPdfUtils {
  51 +
  52 + @Resource
  53 + private OrderBaseInfoService orderBaseInfoService;
  54 +
  55 + @Resource
  56 + private OrderProfitAnalysisService profitAnalysisService;
  57 + @Resource
  58 + private LocalStorageService localStorageService;
  59 +
  60 + @Value("${file.path}")
  61 + private String path;
  62 +
  63 + public List<OrderProducePdfVO> build(List<Long> ids) {
  64 + List<OrderBaseInfoDO> orderBaseInfoDOList = orderBaseInfoService.list(new LambdaQueryWrapper<OrderBaseInfoDO>()
  65 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  66 + .in(OrderBaseInfoDO::getId, ids));
  67 + Set<String> productionDepartments = orderBaseInfoDOList.stream().map(OrderBaseInfoDO::getProductionDepartment).filter(Objects::nonNull)
  68 + .filter(department -> !department.trim().isEmpty()).collect(Collectors.toSet());
  69 + if (productionDepartments.size() > 1) {
  70 + throw new BusinessException("订单中包含多个不同生产科,请重新选择!");
  71 + }
  72 + //得到所选订单的创建人。
  73 + Set<String> createByList = orderBaseInfoDOList.stream().map(OrderBaseInfoDO::getCreateBy).collect(Collectors.toSet());
  74 + //得到所选订单的业务员。
  75 + Set<String> businessPersonList=orderBaseInfoDOList.stream().map(OrderBaseInfoDO::getBusinessPerson).collect(Collectors.toSet());
  76 + //去重。
  77 + HashSet<String> setPerson = new HashSet<>(createByList);
  78 + setPerson.addAll(businessPersonList);
  79 + List<String> personList= new ArrayList<>(setPerson);
  80 + Set<Long> orderIds = orderBaseInfoDOList.stream().map(OrderBaseInfoDO::getId).collect(Collectors.toSet());
  81 + List<OrderProfitAnalysisDO> profitAnalysisDOS = profitAnalysisService.list(new LambdaQueryWrapper<OrderProfitAnalysisDO>().in(OrderProfitAnalysisDO::getOrderId, orderIds));
  82 + Map<Long, OrderProfitAnalysisDO> profitAnalysisDOMap = profitAnalysisDOS.stream().collect(Collectors.toMap(OrderProfitAnalysisDO::getOrderId, Function.identity()));
  83 + return orderBaseInfoDOList.stream().map(x -> {
  84 + OrderProducePdfVO producePdfVO = new OrderProducePdfVO();
  85 + BeanUtils.copyProperties(x, producePdfVO);
  86 + OrderProfitAnalysisDO profitAnalysisDO = profitAnalysisDOMap.get(x.getId());
  87 + if (Objects.nonNull(profitAnalysisDO)) {
  88 + producePdfVO.setProductionDepartmentPrice(profitAnalysisDO.getProductionDepartmentPrice());
  89 + producePdfVO.setProductionDepartmentTotalPrice(profitAnalysisDO.getProductionDepartmentTotalPrice());
  90 + }
  91 + producePdfVO.setPersonList(personList);
  92 + return producePdfVO;
  93 + }).collect(Collectors.toList());
  94 + }
  95 +
  96 + /**
  97 + * @param pdfVOList
  98 + * @param fileName
  99 + * @return
  100 + */
  101 + public ProducePdfVO createProducePdf(List<OrderProducePdfVO> pdfVOList, String fileName, String companyName) {
  102 + Set<String> productionDepartments = pdfVOList.stream().map(OrderProducePdfVO::getProductionDepartment).filter(Objects::nonNull)
  103 + .filter(department -> !department.trim().isEmpty())
  104 + .collect(Collectors.toSet());
  105 + if (productionDepartments.size() > 1) {
  106 + throw new BusinessException("订单中包含多个不同生产科,请重新选择!");
  107 + }
  108 + String pathUri = path + "pdfs" + File.separator + AliOssUtil.getUniqueFileName(companyName);
  109 + OutputStream os = FileUtil.getOutputStream(pathUri);
  110 + XEasyPdfDocument document = createProducePdf(pdfVOList, companyName);
  111 + document.save(os);
  112 + File file = FileUtil.file(pathUri);
  113 + FileRespVO fileRespVO = localStorageService.getFilePath(file,companyName);
  114 + ProducePdfVO producePdfVO = new ProducePdfVO();
  115 + producePdfVO.setProductionUrl(fileRespVO.getFileUrl());
  116 + producePdfVO.setProductionDepartment(productionDepartments.iterator().next());
  117 + //得到订单的创建人和业务员。
  118 + producePdfVO.setProductionDepartment(productionDepartments.iterator().next());
  119 + Optional<List<String>> firstElementFromSet1 = pdfVOList.stream().findFirst().map(OrderProducePdfVO::getPersonList);
  120 + List<String> personList = firstElementFromSet1.orElse(Collections.emptyList());
  121 + producePdfVO.setPersonList(personList);
  122 + return producePdfVO;
  123 + }
  124 +
  125 + /**
  126 + * @param pdfVOList
  127 + * @return
  128 + */
  129 + public XEasyPdfDocument createProducePdf(List<OrderProducePdfVO> pdfVOList, String companyName) {
  130 + // 构建文档
  131 + XEasyPdfDocument document = XEasyPdfHandler.Document.build();
  132 + /* try {
  133 + // 表格
  134 + XEasyPdfTable table = createTable(pdfVOList, companyName);
  135 + XEasyPdfPage page = XEasyPdfHandler.Page.build(XEasyPdfPageRectangle.create(1700F, pdfVOList.size() * 500F), table);
  136 + if(pdfVOList.size()==1){
  137 + page = XEasyPdfHandler.Page.build(XEasyPdfPageRectangle.create(1700F, pdfVOList.size() * 1000F), table);
  138 + }else if(pdfVOList.size()==2){
  139 + // 创建页面
  140 + page = XEasyPdfHandler.Page.build(XEasyPdfPageRectangle.create(1700F, pdfVOList.size() * 500F), table);
  141 + } else if (pdfVOList.size()==3) {
  142 + page = XEasyPdfHandler.Page.build(XEasyPdfPageRectangle.create(1700F, pdfVOList.size() * 333F), table);
  143 + } else if (pdfVOList.size()==4) {
  144 + page = XEasyPdfHandler.Page.build(XEasyPdfPageRectangle.create(1700F, pdfVOList.size() * 250F), table);
  145 + } else if (pdfVOList.size()==5) {
  146 + page = XEasyPdfHandler.Page.build(XEasyPdfPageRectangle.create(1700F, pdfVOList.size() * 200F), table);
  147 + } else if (pdfVOList.size()==6) {
  148 + page = XEasyPdfHandler.Page.build(XEasyPdfPageRectangle.create(1700F, pdfVOList.size() * 166F), table);
  149 + } else if (pdfVOList.size()==7) {
  150 + page = XEasyPdfHandler.Page.build(XEasyPdfPageRectangle.create(1700F, pdfVOList.size() * 142F), table);
  151 + } else if (pdfVOList.size()==8) {
  152 + page = XEasyPdfHandler.Page.build(XEasyPdfPageRectangle.create(1700F, pdfVOList.size() * 125F), table);
  153 + } else if (pdfVOList.size()==9) {
  154 + page = XEasyPdfHandler.Page.build(XEasyPdfPageRectangle.create(1700F, pdfVOList.size() * 111F), table);
  155 + } else {
  156 + page = XEasyPdfHandler.Page.build(XEasyPdfPageRectangle.create(1700F, pdfVOList.size() * 100F), table);
  157 + }
  158 + // 将页面添加到文档
  159 + document.addPage(page);
  160 + // 添加页脚
  161 + document.setGlobalFooter(XEasyPdfHandler.Footer.build(
  162 + //构建文本(使用当前页占位符)
  163 + XEasyPdfHandler.Text.build(
  164 + XEasyPdfHandler.Page.getCurrentPagePlaceholder() +
  165 + "/" +
  166 + XEasyPdfHandler.Page.getTotalPagePlaceholder()).
  167 + setFontSize(10F).setHorizontalStyle(XEasyPdfPositionStyle.CENTER).
  168 + setDefaultFontStyle(XEasyPdfDefaultFontStyle.LIGHT)
  169 + ));
  170 + // 开启总页码占位符替换
  171 + document.enableReplaceTotalPagePlaceholder();
  172 + return document;
  173 + } catch (Exception e) {
  174 + return null;
  175 + }*/
  176 +
  177 + //第二版 线上版。
  178 + try{
  179 +//设置页面大小(1700F宽,1000F高)
  180 + XEasyPdfPageRectangle pageSize=XEasyPdfPageRectangle.create(1700F,1000F);
  181 +
  182 +//计算订单的总数和总价
  183 + Integer totalOrderCount=0;
  184 + BigDecimal totalPrice=new BigDecimal(Constant.ZERO);
  185 +
  186 +//计算所有订单的总量和总价
  187 + for(OrderProducePdfVO producePdfVO:pdfVOList){
  188 + totalOrderCount+=Objects.nonNull(producePdfVO.getOrderCount())?producePdfVO.getOrderCount():Constant.ZERO;
  189 + totalPrice=totalPrice.add(new BigDecimal(Objects.nonNull(producePdfVO.getProductionDepartmentTotalPrice())?producePdfVO.getProductionDepartmentTotalPrice():Constant.ZERO).setScale(2,RoundingMode.HALF_UP));
  190 + }
  191 +
  192 + int currentIndex=1;//初始化当前记录的编号
  193 + int totalRows=pdfVOList.size();//获取总行数
  194 + int currentPageRows=0;//当前页面行数计数器
  195 + List<OrderProducePdfVO>currentPageData=new ArrayList<>();//当前页的数据
  196 + boolean isLastPage=false;//标记是否为最后一页
  197 +
  198 + for(int i=0;i<totalRows;i++){
  199 + OrderProducePdfVO producePdfVO=pdfVOList.get(i);
  200 + currentPageData.add(producePdfVO);//将当前订单数据加入当前页面的数据列表
  201 + currentPageRows++;//当前页面行数+1
  202 +
  203 +//动态计算当前页面是否满了(基于内容长度和当前页面行数)
  204 + if(isPageFull(producePdfVO,currentPageRows)||i==totalRows-1){
  205 + isLastPage=(i==totalRows-1);//如果是最后一条记录,则标记为最后一页
  206 +
  207 +//创建表格并填充数据
  208 + XEasyPdfTable table=createTable(currentPageData,companyName,currentIndex,isLastPage,totalOrderCount,totalPrice);
  209 + currentIndex+=currentPageData.size();//更新编号
  210 +
  211 +//创建并添加页面
  212 + XEasyPdfPage pdfPage=XEasyPdfHandler.Page.build(pageSize,table);
  213 + document.addPage(pdfPage);
  214 +
  215 +//清空当前页数据,准备下一页
  216 + currentPageData.clear();
  217 + currentPageRows=0;
  218 + }
  219 + }
  220 +
  221 +//添加页脚以显示页码
  222 + document.setGlobalFooter(XEasyPdfHandler.Footer.build(
  223 + XEasyPdfHandler.Text.build(
  224 + XEasyPdfHandler.Page.getCurrentPagePlaceholder()+"/"+XEasyPdfHandler.Page.getTotalPagePlaceholder())
  225 + .setFontSize(10F)
  226 + .setHorizontalStyle(XEasyPdfPositionStyle.CENTER)
  227 + .setDefaultFontStyle(XEasyPdfDefaultFontStyle.LIGHT)
  228 + ));
  229 +
  230 +//开启总页码占位符替换
  231 + document.enableReplaceTotalPagePlaceholder();
  232 +
  233 +//返回生成的PDF文档
  234 + return document;
  235 + }catch(Exception e){
  236 + e.printStackTrace();
  237 + return null;
  238 + }
  239 + }
  240 +
  241 + /**
  242 + * @param imageFile
  243 + * @param width
  244 + * @return
  245 + */
  246 + private XEasyPdfCell createImageCell(File imageFile, float width) {
  247 + XEasyPdfImage image = XEasyPdfHandler.Image.build(imageFile).
  248 + setHeight(40F).setWidth(80F).
  249 + setMarginTop(0F).setMarginLeft(0F).
  250 + setVerticalStyle(XEasyPdfPositionStyle.CENTER).setHorizontalStyle(XEasyPdfPositionStyle.CENTER);
  251 +
  252 + XEasyPdfCell cell = XEasyPdfHandler.Table.Row.Cell.build(width, 60F).
  253 + addContent(image).
  254 + setVerticalStyle(XEasyPdfPositionStyle.CENTER).
  255 + setHorizontalStyle(XEasyPdfPositionStyle.CENTER).
  256 + enableCenterStyle().enableComponentSelfStyle();
  257 + return cell;
  258 + }
  259 +
  260 + private XEasyPdfCell createImageCell(InputStream imageStream, float width,float height) {
  261 + XEasyPdfImage image = XEasyPdfHandler.Image.build(imageStream, XEasyPdfImageType.PNG).
  262 + setHeight(250F).setWidth(250F).
  263 + setMarginTop(0F).setMarginLeft(0F).
  264 + setVerticalStyle(XEasyPdfPositionStyle.CENTER).setHorizontalStyle(XEasyPdfPositionStyle.CENTER);
  265 +
  266 + XEasyPdfCell cell = XEasyPdfHandler.Table.Row.Cell.build(width, height).
  267 + addContent(image).
  268 + setVerticalStyle(XEasyPdfPositionStyle.CENTER).
  269 + setHorizontalStyle(XEasyPdfPositionStyle.CENTER).
  270 + enableCenterStyle().enableComponentSelfStyle();
  271 + return cell;
  272 + }
  273 +
  274 + /**
  275 + * @param text
  276 + * @param width
  277 + * @return
  278 + */
  279 + private XEasyPdfCell createCell(String text, float width, float fontSize) {
  280 + XEasyPdfCell cell = XEasyPdfHandler.Table.Row.Cell.build(width, 50F).
  281 + addContent(XEasyPdfHandler.Text.build(text).
  282 + setVerticalStyle(XEasyPdfPositionStyle.CENTER).
  283 + setHorizontalStyle(XEasyPdfPositionStyle.CENTER).
  284 + setDefaultFontStyle(XEasyPdfDefaultFontStyle.LIGHT).setFontSize(fontSize)).
  285 + enableCenterStyle().enableComponentSelfStyle();
  286 + return cell;
  287 + }
  288 +
  289 + /**
  290 + * @param text
  291 + * @param width
  292 + * @return
  293 + */
  294 + private XEasyPdfCell createCell(String text, float width, float height, float fontSize, XEasyPdfDefaultFontStyle fontStyle) {
  295 + XEasyPdfCell cell = XEasyPdfHandler.Table.Row.Cell.build(width, height).
  296 + addContent(XEasyPdfHandler.Text.build(text).
  297 + setVerticalStyle(XEasyPdfPositionStyle.CENTER).
  298 + setHorizontalStyle(XEasyPdfPositionStyle.CENTER).
  299 + setDefaultFontStyle(fontStyle).setFontSize(fontSize)).
  300 + enableCenterStyle().enableComponentSelfStyle();
  301 + return cell;
  302 + }
  303 +
  304 + /**
  305 + * @param text
  306 + * @param width
  307 + * @return
  308 + */
  309 + private XEasyPdfCell createCell(String text, float width) {
  310 + XEasyPdfCell cell = XEasyPdfHandler.Table.Row.Cell.build(width).
  311 + addContent(XEasyPdfHandler.Text.build(text).
  312 + setVerticalStyle(XEasyPdfPositionStyle.CENTER).
  313 + setHorizontalStyle(XEasyPdfPositionStyle.CENTER).
  314 + setDefaultFontStyle(XEasyPdfDefaultFontStyle.LIGHT).setFontSize(16)).
  315 + enableCenterStyle().enableComponentSelfStyle();
  316 + return cell;
  317 + }
  318 +
  319 + /**
  320 + * @param text
  321 + * @param width
  322 + * @return
  323 + */
  324 + private XEasyPdfCell createCell(String text, float width, float height, float fontSize,
  325 + XEasyPdfDefaultFontStyle fontStyle,
  326 + XEasyPdfPositionStyle verticalStyle,
  327 + XEasyPdfPositionStyle horizontalStyle) {
  328 + XEasyPdfCell cell = XEasyPdfHandler.Table.Row.Cell.build(width, height).
  329 + addContent(XEasyPdfHandler.Text.build(text).
  330 + setVerticalStyle(verticalStyle).
  331 + setHorizontalStyle(horizontalStyle).
  332 + setDefaultFontStyle(fontStyle).setFontSize(fontSize)).
  333 + enableCenterStyle().enableComponentSelfStyle();
  334 + return cell;
  335 + }
  336 +
  337 + /**
  338 + * @return
  339 + */
  340 + private XEasyPdfTable createTable(List<OrderProducePdfVO> pdfVOList, String companyName, int startIndex,boolean isLastPage,Integer totalOrderCount, BigDecimal totalPrice) throws Exception {
  341 + XEasyPdfTable table = XEasyPdfHandler.Table.build();
  342 + List<XEasyPdfRow> rowList = new ArrayList<>();
  343 + List<XEasyPdfCell> cellList = new ArrayList<>(15);
  344 + List<XEasyPdfCell> header = new ArrayList<>(1);
  345 + if ("青岛吉庆天成饰品有限公司".equals(companyName)) {
  346 + header.add(createCell("青岛吉庆天成生产订单", 1660F, 70F, 24F, XEasyPdfDefaultFontStyle.BOLD));
  347 + } else {
  348 + header.add(createCell("青岛翱特逸格生产订单", 1660F, 70F, 24F, XEasyPdfDefaultFontStyle.BOLD));
  349 + }
  350 + rowList.add(XEasyPdfHandler.Table.Row.build(header));
  351 + // 第一行设置表头,默认标题
  352 + cellList.add(createCell("编号", 50F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  353 + cellList.add(createCell("项目号", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  354 + cellList.add(createCell("生产科", 90F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  355 + cellList.add(createCell("内部编号", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  356 + cellList.add(createCell("客户订单号", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  357 + cellList.add(createCell("客户款号", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  358 + cellList.add(createCell("REFERENCE", 100F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  359 + cellList.add(createCell("订单颜色", 120F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  360 + cellList.add(createCell("颜色中文", 100F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  361 + cellList.add(createCell("订单图片", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  362 + cellList.add(createCell("产品意见", 150F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  363 + cellList.add(createCell("订单数量", 90F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  364 + cellList.add(createCell("生产科交期", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  365 + cellList.add(createCell("包装类型", 80F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  366 + cellList.add(createCell("生产科单价", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  367 + cellList.add(createCell("生产科总价", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  368 + rowList.add(XEasyPdfHandler.Table.Row.build(cellList));
  369 +
  370 + for (int i = 0; i < pdfVOList.size(); i++) {
  371 + OrderProducePdfVO producePdfVO = pdfVOList.get(i);
  372 + String productionDepartmentConsignTime = StringUtils.isNotBlank(producePdfVO.getProductionDepartmentConsignTime()) ?
  373 + DateUtils.format(DateUtils.parseDate(producePdfVO.getProductionDepartmentConsignTime(), DateUtils.DATE_TIME), DateUtils.DATE) : "";
  374 +
  375 + List<XEasyPdfCell> dataCellList = new ArrayList<>(15);
  376 + dataCellList.add(createCell("" + (startIndex + i), 50F)); // 使用连续编号
  377 + dataCellList.add(createCell(StringUtils.isNotEmpty(producePdfVO.getProjectNo()) ? producePdfVO.getProjectNo() : "", 110F));
  378 + dataCellList.add(createCell(StringUtils.isNotEmpty(producePdfVO.getProductionDepartment()) ? producePdfVO.getProductionDepartment() : "", 90F));
  379 + dataCellList.add(createCell(StringUtils.isNotEmpty(producePdfVO.getInnerNo()) ? producePdfVO.getInnerNo() : "", 110F));
  380 + dataCellList.add(createCell(StringUtils.isNotEmpty(producePdfVO.getCustomerPo()) ? producePdfVO.getCustomerPo() : "", 110F));
  381 + dataCellList.add(createCell(StringUtils.isNotEmpty(producePdfVO.getCustomerStyle()) ? producePdfVO.getCustomerStyle() : "", 110F));
  382 + dataCellList.add(createCell(StringUtils.isNotEmpty(producePdfVO.getModeleLo()) ? producePdfVO.getModeleLo() : "", 100F));
  383 + dataCellList.add(createCell(StringUtils.isNotEmpty(producePdfVO.getPoColor()) ? producePdfVO.getPoColor() : "", 120F));
  384 + dataCellList.add(createCell(StringUtils.isNotEmpty(producePdfVO.getCnColor()) ? producePdfVO.getCnColor() : "", 100F));
  385 + if (StringUtils.isNotBlank(producePdfVO.getPicUrl())) {
  386 + URL url = new URL(producePdfVO.getPicUrl());
  387 + InputStream inputStream = url.openStream();
  388 + File imageFile = FileUtil.inputStreamToFile(inputStream, "order" + System.currentTimeMillis() + ".png");
  389 +
  390 + dataCellList.add(createImageCell(imageFile, 110F));
  391 + } else {
  392 + dataCellList.add(createCell("", 110F));
  393 + }
  394 + dataCellList.add(createCell(StringUtils.isNotEmpty(producePdfVO.getProductionComment()) ? producePdfVO.getProductionComment() : "", 150F));
  395 + if (Constant.ZERO == producePdfVO.getOrderCount()) {
  396 + dataCellList.add(createCell("", 90F));
  397 + } else {
  398 + dataCellList.add(createCell("" + producePdfVO.getOrderCount(), 90F));
  399 + }
  400 + dataCellList.add(createCell(productionDepartmentConsignTime, 110F));
  401 + dataCellList.add(createCell(StringUtils.isNotEmpty(producePdfVO.getPacketType()) ? producePdfVO.getPacketType() : "", 80F));
  402 + dataCellList.add(createCell(Objects.nonNull(producePdfVO.getProductionDepartmentPrice()) ? "" + "¥"+producePdfVO.getProductionDepartmentPrice() : "", 110F));
  403 + dataCellList.add(createCell(Objects.nonNull(producePdfVO.getProductionDepartmentTotalPrice()) ? "" + "¥"+producePdfVO.getProductionDepartmentTotalPrice() : "", 110F));
  404 + rowList.add(XEasyPdfHandler.Table.Row.build(dataCellList));
  405 + }
  406 +
  407 + if (isLastPage) {
  408 + List<XEasyPdfCell> endCellList = new ArrayList<>(15);
  409 + endCellList.add(createCell("合计", 50F, 16F));
  410 + endCellList.add(createCell("", 110F));
  411 + endCellList.add(createCell("", 90F));
  412 + endCellList.add(createCell("", 110F));
  413 + endCellList.add(createCell("", 110F));
  414 + endCellList.add(createCell("", 110F));
  415 + endCellList.add(createCell("", 100F));
  416 + endCellList.add(createCell("", 120F));
  417 + endCellList.add(createCell("", 100F));
  418 + endCellList.add(createCell("", 110F));
  419 + endCellList.add(createCell("", 150F));
  420 + endCellList.add(createCell("" + totalOrderCount, 90F, 16F));
  421 + endCellList.add(createCell("", 110F));
  422 + endCellList.add(createCell("", 80F));
  423 + endCellList.add(createCell("", 110F));
  424 + endCellList.add(createCell("¥" + totalPrice, 110F, 16F));
  425 + rowList.add(XEasyPdfHandler.Table.Row.build(endCellList));
  426 + }
  427 +
  428 + List<XEasyPdfCell> signList = new ArrayList<>(2);
  429 + ClassLoader classLoader = getClass().getClassLoader();
  430 + InputStream imageStream = null;
  431 + if ("青岛吉庆天成饰品有限公司".equals(companyName)) {
  432 + signList.add(createCell("吉庆天成签字+日期:", 680F, 80F, 20F, XEasyPdfDefaultFontStyle.BOLD, XEasyPdfPositionStyle.CENTER, XEasyPdfPositionStyle.LEFT));
  433 + imageStream = classLoader.getResourceAsStream("images/jqtc.png");
  434 + } else {
  435 + signList.add(createCell("翱特逸格签字+日期:", 680F, 80F, 20F, XEasyPdfDefaultFontStyle.BOLD, XEasyPdfPositionStyle.CENTER, XEasyPdfPositionStyle.LEFT));
  436 + imageStream = classLoader.getResourceAsStream("images/alterego.png");
  437 + }
  438 + if (imageStream != null) {
  439 + XEasyPdfCell imageCell = createImageCell(imageStream, 150F,150F);
  440 + // 设置图片超出边框的效果
  441 + imageCell.setMarginLeft(-380F)
  442 + .setMarginTop(0F)
  443 + .disableBorder();
  444 + signList.add(imageCell);
  445 + try {
  446 + imageStream.close();
  447 + } catch (IOException e) {
  448 + System.out.println("关闭图片流时发生错误:" + e.getMessage());
  449 + }
  450 + }else {
  451 + log.info("图片资源未找到或不存在");
  452 + }
  453 +
  454 + signList.add(createCell("外加工签字+日期:", 980F, 80F, 20F, XEasyPdfDefaultFontStyle.BOLD, XEasyPdfPositionStyle.CENTER, XEasyPdfPositionStyle.LEFT).setMarginLeft(230F));
  455 + rowList.add(XEasyPdfHandler.Table.Row.build(signList));
  456 +
  457 + table.addRow(rowList);
  458 + table.setHorizontalStyle(XEasyPdfPositionStyle.CENTER).setMarginLeft(10F).setMarginTop(60F).setMarginBottom(10F);
  459 + return table;
  460 + }
  461 +
  462 +//新代码9:22
  463 +//根据当前行数和"产品意见"的长度动态判断页面是否已经满了
  464 +
  465 + private boolean isPageFull(OrderProducePdfVO producePdfVO,int currentPageRows){
  466 + int maxRowsPerPage=9;//假设初始每页最多可以放10行数据
  467 + int extraRowsForComment=(int)Math.ceil((double)producePdfVO.getProductionComment().length()/25);//假设每50个字符占一行
  468 +//如果当前行数+根据"产品意见"计算出的额外行数超过每页最大行数,返回true表示页面已满
  469 + return(currentPageRows+extraRowsForComment)>=maxRowsPerPage;
  470 + }
  471 +
  472 +}
  473 +//待拷贝end。
0 474 \ No newline at end of file
... ...
src/main/java/com/order/erp/common/utils/OrderFieldUtils.java
... ... @@ -309,6 +309,9 @@ public class OrderFieldUtils {
309 309 if (OrderLockFieldEnum.UN_LOCKED.getStatus().equals(baseFields.getBusinessPerson())) {
310 310 return true;
311 311 }
  312 + if (OrderLockFieldEnum.UN_LOCKED.getStatus().equals(baseFields.getReturnOrder())) {
  313 + return true;
  314 + }
312 315  
313 316 return false;
314 317 }
... ... @@ -358,6 +361,7 @@ public class OrderFieldUtils {
358 361 .productStyle(locked)
359 362 .projectNo(locked)
360 363 .businessPerson(locked)
  364 + .returnOrder(locked)
361 365 .build();
362 366 }
363 367  
... ...
src/main/java/com/order/erp/controller/OrderController.java
... ... @@ -4,6 +4,7 @@ import com.order.erp.common.annotation.AnonymousAccess;
4 4 import com.order.erp.common.constant.ServerResult;
5 5 import com.order.erp.common.excel4j.exceptions.Excel4JException;
6 6 import com.order.erp.common.exception.BusinessException;
  7 +import com.order.erp.domain.vo.ProducePdfVO;
7 8 import com.order.erp.domain.vo.order.*;
8 9 import com.order.erp.mapper.order.OrderBaseInfoMapper;
9 10 import com.order.erp.service.order.OrderBaseInfoService;
... ... @@ -157,6 +158,28 @@ public class OrderController {
157 158 return orderBaseInfoService.check(orderBaseInfoQueryVO);
158 159 }
159 160  
  161 + /**
  162 + * 一次性通过率
  163 + *
  164 + * @param orderOpinionLogVO 查询条件
  165 + * @return 查询结果
  166 + */
  167 + @PostMapping("/passRate")
  168 + @AnonymousAccess
  169 + public ServerResult oneTimePassRate(@RequestBody OrderOpinionLogVO orderOpinionLogVO) {
  170 + return orderBaseInfoService.passRate(orderOpinionLogVO);
  171 + }
  172 +
  173 + @PostMapping("/produceReport")
  174 + public ServerResult produceReport(@RequestBody ProducePdfVO producePdfVO) {
  175 + return orderBaseInfoService.produceReport(producePdfVO);
  176 + }
  177 +
  178 + @PostMapping("/send")
  179 + public ServerResult send(@RequestBody ProducePdfVO producePdfVO) throws Exception {
  180 + return orderBaseInfoService.send(producePdfVO);
  181 + }
  182 +
160 183  
161 184 }
162 185  
... ...
src/main/java/com/order/erp/controller/OrderOpinionLonController.java 0 → 100644
  1 +package com.order.erp.controller;
  2 +
  3 +import com.order.erp.common.annotation.AnonymousAccess;
  4 +import com.order.erp.common.constant.ServerResult;
  5 +import com.order.erp.domain.vo.order.OrderOpinionLogVO;
  6 +import com.order.erp.service.order.OrderOpinionLogService;
  7 +import io.swagger.annotations.Api;
  8 +import io.swagger.annotations.ApiOperation;
  9 +import org.springframework.validation.annotation.Validated;
  10 +import org.springframework.web.bind.annotation.PostMapping;
  11 +import org.springframework.web.bind.annotation.RequestBody;
  12 +import org.springframework.web.bind.annotation.RequestMapping;
  13 +import org.springframework.web.bind.annotation.RestController;
  14 +
  15 +import javax.annotation.Resource;
  16 +
  17 +/**
  18 + *
  19 + * 订单跟单结果记录日志表(OrderOpinionLogDO)表控制层
  20 + * @Author:ch
  21 + * @createTime:2024-08-05
  22 + */
  23 +@Api(tags = "订单跟单结果记录")
  24 +@RestController
  25 +@RequestMapping("/order/erp/opinion/log")
  26 +public class OrderOpinionLonController {
  27 +
  28 + @Resource
  29 + private OrderOpinionLogService orderOpinionLogService;
  30 +
  31 + @PostMapping("/query_by_id")
  32 + @ApiOperation("查询订单的跟单结果记录")
  33 + @AnonymousAccess
  34 + public ServerResult queryById(@RequestBody @Validated OrderOpinionLogVO orderOpinionLogVo){
  35 + return orderOpinionLogService.queryById(orderOpinionLogVo);
  36 + }
  37 +
  38 +}
... ...
src/main/java/com/order/erp/domain/EmailTemplateEnum.java
... ... @@ -15,7 +15,7 @@ public enum EmailTemplateEnum {
15 15  
16 16 CONFIRM_SAMPLE_TEMPLATE("确认样确认状态", "您收到此邮件是因为您未能在规定的期限内完成以下货号的确认样确认,请尽快完成", 1L),
17 17  
18   - OTHER_SAMPLE_TEMPLATE("其他要求样品发送日期", "您收到此邮件是因为您未能在规定的期限内完成以下货号的其他要求样品的发送,请尽快完成", 2L),
  18 + OTHER_SAMPLE_TEMPLATE("EXTRA,SHOWROOM,ONLINE sample发送日期", "您收到此邮件是因为您未能在规定的期限内完成以下货号的EXTRA,SHOWROOM,ONLINE sample的发送,请尽快完成", 2L),
19 19  
20 20 BIG_SAMPLE_TEMPLATE("大货样确认状态", "您收到此邮件是因为您未能在规定的期限内完成以下货号的大货样确认,请尽快完成", 3L),
21 21  
... ... @@ -31,7 +31,9 @@ public enum EmailTemplateEnum {
31 31  
32 32 END_CHECK_REPORT_TEMPLATE("尾期验货报告", "您好,请查收尾期验货报告", 9L),
33 33  
34   - PRODUCE_INDICATE_REPORT("生产指示书报告","你好,请查收附件生产订单",10L),
  34 + PRODUCE_INDICATE_REPORT("生产指示书","你好,请查收附件生产订单",10L),
  35 +
  36 + PRODUCE_IDEA("产品意见信息","你好,请查收产品意见信息",11L),
35 37  
36 38 ;
37 39  
... ...
src/main/java/com/order/erp/domain/OrderOpinionLogEnum.java 0 → 100644
  1 +package com.order.erp.domain;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Getter;
  5 +//待拷贝START。
  6 +
  7 +/**
  8 + * @Author:ch
  9 + * @createTime:2024-08-05
  10 + */
  11 +
  12 +@Getter
  13 +@AllArgsConstructor
  14 +public enum OrderOpinionLogEnum {
  15 + ORDER_PRODUCTION_COMMENT("productionComment","产品意见"),
  16 + ORDER_PP_CONFIRRM_RESULT("ppConfirmResult","pp样品确认意见"),
  17 + ORDER_SHIPMENT_SAMPLE_CONFIRM_RESULT("shippmentSampleConfirmResult","shipment sample确认意见"),
  18 + ORDER_AITEX_TEST_FINISH_RESULT("aitexTestResult","Altex测试结果"),
  19 + ORDER_SGS_TEST_FINISH_RESULT("sgsTestFinishResult","SGS测试结果"),
  20 + ;
  21 + private String type;
  22 +
  23 + private String desc;
  24 +}
  25 +//待拷贝END。
0 26 \ No newline at end of file
... ...
src/main/java/com/order/erp/domain/dto/order/OrderBaseInfoDO.java
... ... @@ -115,4 +115,9 @@ public class OrderBaseInfoDO extends BaseDO implements Serializable {
115 115 * 业务员
116 116 */
117 117 private String businessPerson;
  118 +
  119 + /**
  120 + * 是否返单
  121 + */
  122 + private String returnOrder;
118 123 }
... ...
src/main/java/com/order/erp/domain/dto/order/OrderOpinionLogDO.java 0 → 100644
  1 +package com.order.erp.domain.dto.order;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.TableName;
  4 +import com.order.erp.domain.dto.BaseDO;
  5 +import lombok.*;
  6 +import lombok.experimental.SuperBuilder;
  7 +
  8 +import java.io.Serializable;
  9 +
  10 +/**
  11 + * @Author:ch
  12 + * @createTime:2024-08-05
  13 + * @Description:订单跟单结果记录日志表。
  14 + */
  15 +//待拷贝start。
  16 +@TableName("order_opinion_log")
  17 +@Data
  18 +@AllArgsConstructor
  19 +@ToString
  20 +@NoArgsConstructor
  21 +@EqualsAndHashCode(callSuper = false)
  22 +@SuperBuilder
  23 +public class OrderOpinionLogDO extends BaseDO implements Serializable {
  24 + private Long id;
  25 +
  26 + /**
  27 + * 订单id
  28 + */
  29 + private Long orderId;
  30 + /**
  31 + * 意见类型(SGS/Aitex/SHIPPMENT/PP/产品意见)
  32 + */
  33 + private String opinionType;
  34 +
  35 + /**
  36 + * 更新字段
  37 + */
  38 + private String field;
  39 +}
  40 +//待拷贝end。
0 41 \ No newline at end of file
... ...
src/main/java/com/order/erp/domain/pdf/OrderProducePdfVO.java 0 → 100644
  1 +package com.order.erp.domain.pdf;
  2 +
  3 +import lombok.*;
  4 +import lombok.experimental.SuperBuilder;
  5 +
  6 +import java.io.Serializable;
  7 +import java.util.List;
  8 +//待拷贝start。
  9 +
  10 +/**
  11 + * 生产指示书pdf
  12 + *
  13 + * @author makejava
  14 + * @since 2023-09-08 15:26:43
  15 + */
  16 +@Data
  17 +@AllArgsConstructor
  18 +@ToString
  19 +@NoArgsConstructor
  20 +@EqualsAndHashCode(callSuper = false)
  21 +@SuperBuilder
  22 +public class OrderProducePdfVO implements Serializable {
  23 +
  24 + /**
  25 + * 项目号
  26 + */
  27 + private String projectNo;
  28 +
  29 + /**
  30 + * 生产科
  31 + */
  32 + private String productionDepartment;
  33 +
  34 + /**
  35 + * 内部编号
  36 + */
  37 + private String innerNo;
  38 +
  39 + /**
  40 + * 客户po号(客户订单号)
  41 + */
  42 + private String customerPo;
  43 +
  44 + /**
  45 + * 客户STYLE#(客户款号)
  46 + */
  47 + private String customerStyle;
  48 + /**
  49 + * Modelo(REFERENCE)
  50 + */
  51 + private String modeleLo;
  52 + /**
  53 + * PO COLOR (订单颜色)
  54 + */
  55 + private String poColor;
  56 +
  57 + /**
  58 + * 颜色中文
  59 + */
  60 + private String cnColor;
  61 +
  62 + /**
  63 + * pic图片地址(订单图片)
  64 + */
  65 + private String picUrl;
  66 +
  67 + /**
  68 + * 产品意见
  69 + */
  70 + private String productionComment;
  71 +
  72 + /**
  73 + * 订单数量
  74 + */
  75 + private Integer orderCount;
  76 +
  77 + /**
  78 + * 生成科拖货时间(生产科交期)
  79 + */
  80 + private String productionDepartmentConsignTime;
  81 +
  82 + /**
  83 + * 包装类型
  84 + */
  85 + private String packetType;
  86 +
  87 + /**
  88 + * 生成科单价¥
  89 + */
  90 + private Double productionDepartmentPrice;
  91 +
  92 + /**
  93 + * 生成科总价¥
  94 + */
  95 + private Double productionDepartmentTotalPrice;
  96 + /**
  97 + * 注意:创建订单的用户以及订单对应的业务员 这个不需要导出
  98 + */
  99 + private List<String> personList;
  100 +
  101 +}
  102 +//待拷贝end。
0 103 \ No newline at end of file
... ...
src/main/java/com/order/erp/domain/vo/ProducePdfVO.java 0 → 100644
  1 +package com.order.erp.domain.vo;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +import lombok.ToString;
  7 +
  8 +import java.util.List;
  9 +
  10 +@Data
  11 +@AllArgsConstructor
  12 +@NoArgsConstructor
  13 +@ToString
  14 +public class ProducePdfVO {
  15 +
  16 + private List<Long> ids;
  17 +
  18 + private String companyName;
  19 + /**
  20 + * 生产科
  21 + */
  22 + private String productionDepartment;
  23 +
  24 + private String productionUrl;
  25 +
  26 + private Boolean isSend;
  27 + private List<String> personList;
  28 +
  29 +}
... ...
src/main/java/com/order/erp/domain/vo/order/OrderBaseFieldVO.java
... ... @@ -106,4 +106,9 @@ public class OrderBaseFieldVO implements Serializable {
106 106 */
107 107 private String businessPerson = OrderLockFieldEnum.LOCKED.getStatus();
108 108  
  109 + /**
  110 + * 是否返单
  111 + */
  112 + private String returnOrder = OrderLockFieldEnum.LOCKED.getStatus();
  113 +
109 114 }
... ...
src/main/java/com/order/erp/domain/vo/order/OrderBaseInfoVO.java
... ... @@ -117,4 +117,9 @@ public class OrderBaseInfoVO implements Serializable {
117 117 */
118 118 private String businessPerson;
119 119  
  120 + /**
  121 + * 是否返单
  122 + */
  123 + private String returnOrder;
  124 +
120 125 }
121 126 \ No newline at end of file
... ...
src/main/java/com/order/erp/domain/vo/order/OrderOpinionLogVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import lombok.*;
  4 +import lombok.experimental.SuperBuilder;
  5 +
  6 +import java.util.List;
  7 +//待拷贝start。
  8 +
  9 +/**
  10 + * @Author:ch
  11 + * @createTime:2024-08-07
  12 + */
  13 +@Data
  14 +@AllArgsConstructor
  15 +@ToString
  16 +@NoArgsConstructor
  17 +@EqualsAndHashCode(callSuper = false)
  18 +@SuperBuilder
  19 +public class OrderOpinionLogVO {
  20 + private List<Long> ids;
  21 +
  22 + /**
  23 + * 订单id
  24 + */
  25 + private Long orderId;
  26 + /**
  27 + * 意见类型(SGS/Aitex/SHIPPMENT/PP/产品意见)
  28 + */
  29 + private String opinionType;
  30 +
  31 + /**
  32 + * 更新字段
  33 + */
  34 + private String field;
  35 +}
  36 +//待拷贝end。
0 37 \ No newline at end of file
... ...
src/main/java/com/order/erp/job/OrderOverTimeEventJob.java
... ... @@ -8,20 +8,28 @@ import com.order.erp.common.constant.Constant;
8 8 import com.order.erp.common.utils.*;
9 9 import com.order.erp.domain.EmailTemplateEnum;
10 10 import com.order.erp.domain.OrderEventEnum;
  11 +import com.order.erp.domain.RoleEnum;
11 12 import com.order.erp.domain.dto.BaseDO;
  13 +import com.order.erp.domain.dto.admin.AdminRoleDO;
12 14 import com.order.erp.domain.dto.admin.AdminUserDO;
  15 +import com.order.erp.domain.dto.admin.AdminUserRoleDO;
13 16 import com.order.erp.domain.dto.order.OrderBaseInfoDO;
14 17 import com.order.erp.domain.dto.order.OrderInspectionStageDO;
15 18 import com.order.erp.domain.dto.order.OrderTrackStageDO;
16 19 import com.order.erp.domain.dto.order.ReceiveEmailMappingDO;
17 20 import com.order.erp.domain.vo.order.*;
  21 +import com.order.erp.service.admin.AdminRoleService;
  22 +import com.order.erp.service.admin.AdminUserRoleService;
18 23 import com.order.erp.service.admin.AdminUserService;
19 24 import com.order.erp.service.order.*;
20 25 import lombok.extern.slf4j.Slf4j;
21 26 import org.springframework.scheduling.annotation.Scheduled;
22 27 import org.springframework.stereotype.Component;
  28 +import org.w3c.dom.events.Event;
  29 +
23 30 import javax.annotation.Resource;
24 31 import java.time.LocalDate;
  32 +import java.time.format.DateTimeFormatter;
25 33 import java.time.temporal.ChronoUnit;
26 34 import java.util.*;
27 35 import java.util.concurrent.TimeUnit;
... ... @@ -61,9 +69,11 @@ public class OrderOverTimeEventJob {
61 69  
62 70 @Resource
63 71 private AdminUserService adminUserService;
  72 + @Resource
  73 + private AdminUserRoleService adminUserRoleService;
64 74  
65 75 /**
66   - * 凌晨5点执行,一天一次
  76 + * 凌晨1点执行,一天一次
67 77 */
68 78  
69 79 @Scheduled(cron = "0 0 5 * * ?")
... ... @@ -119,8 +129,8 @@ public class OrderOverTimeEventJob {
119 129 return null;
120 130 }).filter(Objects::nonNull)
121 131 .collect(Collectors.toList());
122   - //如果为尾期验货事件的话,需要从订单中的生产科角色中得到邮箱。而不是从邮件配置中得到邮箱。
123   - if (OrderEventEnum.END_CHECK_DATE_EVENT.equals(eventEnum) ) {
  132 + //如果为尾期验货事件的话,需要从订单中的生产科角色中得到邮箱。而不是从邮件配置中得到邮箱。并且还需要发送给所有的质检员。
  133 + if (OrderEventEnum.END_CHECK_DATE_EVENT.equals(eventEnum)) {
124 134 for (OrderEventJobVO orderEventJob : eventJobVOS) {
125 135 if (!redisUtils.hasKey(EmailTemplateEnum.byTemplate(
126 136 eventEnum.getTemplateId()) + Constant.CROSS_BAR_CHARACTER + orderEventJob.getBaseInfo().getId())) {
... ... @@ -133,17 +143,60 @@ public class OrderOverTimeEventJob {
133 143 AdminUserDO productionDepartmentUser = adminUserService.getOne(new LambdaQueryWrapper<AdminUserDO>()
134 144 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
135 145 .eq(AdminUserDO::getUserName, productionDepartment));
136   - if(Objects.nonNull(productionDepartmentUser) && StringUtils.isNotBlank(productionDepartmentUser.getEmail())){
  146 + //得到所有的质检员。由于删除了角色,但是用户角色表中的信息没有删除,所以不能直接通过用户角色表拿角色,然后发邮件,需校验。
  147 + List<AdminUserRoleDO> UserRoleList = adminUserRoleService.list(new LambdaQueryWrapper<AdminUserRoleDO>()
  148 + .eq(AdminUserRoleDO::getRoleId, RoleEnum.INSPECT_USER.getId()));
  149 + Set<Long> userIdList = UserRoleList.stream().map(AdminUserRoleDO::getUserId).collect(Collectors.toSet());
  150 + List<AdminUserDO> produceList = adminUserService.list(new LambdaQueryWrapper<AdminUserDO>()
  151 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  152 + .in(AdminUserDO::getId, userIdList)
  153 + .eq(AdminUserDO::getStatus,Constant.ENABLE_TEN));
  154 + List<String> produceEmailList = produceList.stream().map(AdminUserDO::getEmail).filter(Objects::nonNull)
  155 + .flatMap(email -> Arrays.asList(email.split("[,,]+")).stream())
  156 + .map(String::trim)
  157 + .filter(s -> !s.isEmpty())
  158 + .collect(Collectors.toList());
  159 + log.info("------------------------------------------------------------------------------------");
  160 + //得到订单的尾期验货日期的邮件配置中的邮箱。
  161 + LambdaQueryWrapper<ReceiveEmailMappingDO> receiveEmailMappingDOLambdaQueryWrapper = new LambdaQueryWrapper<>();
  162 + receiveEmailMappingDOLambdaQueryWrapper.eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN);
  163 + if(!orderEventJob.getBaseInfo().getCustomerCode().contains("-") && !orderEventJob.getBaseInfo().getCustomerCode().contains("——")){
  164 + receiveEmailMappingDOLambdaQueryWrapper.eq(ReceiveEmailMappingDO::getTypeValue, orderEventJob.getBaseInfo().getCustomerCode())
  165 + .last("limit 1");
  166 + }else{
  167 + receiveEmailMappingDOLambdaQueryWrapper.like(ReceiveEmailMappingDO::getTypeValue, orderEventJob.getBaseInfo().getCustomerCode().split("-")[0])
  168 + .last("limit 1");
  169 + }
  170 + ReceiveEmailMappingDO receiveEmailMappingDO = receiveEmailMappingService.getOne( receiveEmailMappingDOLambdaQueryWrapper);
  171 + List<String> emailList = new ArrayList<>();
  172 + if (Objects.nonNull(receiveEmailMappingDO)) {
  173 + List<ReceiveEmailConfigItemVO> receiveEmailConfigItemVOList = JSON.parseObject(
  174 + receiveEmailMappingDO.getConfigInfos(), new TypeReference<List<ReceiveEmailConfigItemVO>>() {
  175 + });
  176 + for (ReceiveEmailConfigItemVO item : receiveEmailConfigItemVOList) {
  177 + if (eventEnum.getEvent().equals(item.getEvent())) {
  178 + emailList = item.getEmails();
  179 + }
  180 + }
  181 + }
  182 + if (Objects.nonNull(productionDepartmentUser) && CollectionUtils.isNotEmpty(emailList)) {
  183 + List<String> emails = emailList.stream().flatMap(email -> Arrays.stream(email.split("[,,]+"))).collect(Collectors.toList());
137 184 List<String> productionEmail = Arrays.asList(productionDepartmentUser.getEmail().split("[,,]+"))
138 185 .stream().map(String::trim)
  186 + .filter(Objects::nonNull)
139 187 .collect(Collectors.toList());
  188 + List<String> combineEmail = new ArrayList<>(emails);
  189 + if(CollectionUtils.isNotEmpty(produceEmailList)){
  190 + combineEmail.addAll(produceEmailList);
  191 + }
  192 + combineEmail.addAll(productionEmail);
140 193 emailSendUtils.sendEmail(EmailTemplateEnum.byTemplate(eventEnum.getTemplateId()),
141   - productionEmail, orderEventJob);
  194 + combineEmail, orderEventJob);
142 195 redisUtils.set(EmailTemplateEnum.byTemplate(
143   - eventEnum.getTemplateId()) + Constant.CROSS_BAR_CHARACTER +orderEventJob.getBaseInfo().getId(),
  196 + eventEnum.getTemplateId()) + Constant.CROSS_BAR_CHARACTER + orderEventJob.getBaseInfo().getId(),
144 197 orderEventJob, 90, TimeUnit.DAYS);
145 198 }
146   -
  199 + log.info("------------------------------------------------------------------------------------");
147 200 }
148 201 }
149 202 } else {
... ... @@ -281,7 +334,13 @@ public class OrderOverTimeEventJob {
281 334 String ppConfirmResult = eventJobVO.getTrackStageInfo().getPpConfirmResult();
282 335 if (StringUtils.isNotBlank(orderHodTime) && StringUtils.isNotBlank(ppConfirmResult) && StringUtils.isNotBlank(ppConfirmTime)) {
283 336 int daysBetween = getDaysBetween(ppConfirmResult, ppConfirmTime, orderHodTime);
284   - if (daysBetween == Constant.TWENTY_FIRST || daysBetween == Constant.NEGATIVE_ONE) {
  337 + if (Constant.TWENTY_FIRST == daysBetween|| Constant.NEGATIVE_ONE ==daysBetween) {
  338 + return true;
  339 + }
  340 + } else {
  341 + LocalDate today = LocalDate.now();
  342 + LocalDate localDate = DateUtils.parseDate(orderHodTime);
  343 + if (Constant.TWENTY_FIRST == (int) ChronoUnit.DAYS.between(today, localDate) && StringUtils.isEmpty(ppConfirmResult)) {
285 344 return true;
286 345 }
287 346 }
... ... @@ -290,15 +349,11 @@ public class OrderOverTimeEventJob {
290 349  
291 350 private Boolean filterOtherSampleEvent(OrderEventJobVO eventJobVO) {
292 351 String orderHodTime = eventJobVO.getBaseInfo().getOrderHodTime();
293   - String esoSampleSendTime = eventJobVO.getTrackStageInfo().getEsoSampleSendTime();
294   - if (StringUtils.isNotBlank(orderHodTime) && StringUtils.isNotBlank(esoSampleSendTime)) {
295   - LocalDate orderHodTimelocalDate = DateUtils.parseDate(orderHodTime);
296   - LocalDate esoSampleSendTimelocalDate = DateUtils.parseDate(esoSampleSendTime);
297   - if (ChronoUnit.DAYS.between(esoSampleSendTimelocalDate, orderHodTimelocalDate) == Constant.FOURTEEN) {
  352 + LocalDate today = LocalDate.now();
  353 + LocalDate localDate = DateUtils.parseDate(orderHodTime);
  354 + if ( Constant.FOURTEEN==(int) ChronoUnit.DAYS.between(today, localDate) && StringUtils.isBlank(eventJobVO.getTrackStageInfo().getEsoSampleSendTime())) {
298 355 return true;
299 356 }
300   -
301   - }
302 357 return false;
303 358 }
304 359  
... ... @@ -308,7 +363,13 @@ public class OrderOverTimeEventJob {
308 363 String shippmentSampleConfirmTime = eventJobVO.getTrackStageInfo().getShippmentSampleConfirmTime();
309 364 if (StringUtils.isNotBlank(orderHodTime) && StringUtils.isNotBlank(shippmentSampleConfirmResult) && StringUtils.isNotBlank(shippmentSampleConfirmTime)) {
310 365 int daysBetween = getDaysBetween(shippmentSampleConfirmResult, shippmentSampleConfirmTime, orderHodTime);
311   - if (daysBetween == Constant.SEVEN || daysBetween == Constant.NEGATIVE_ONE) {
  366 + if ( Constant.SEVEN ==daysBetween || Constant.NEGATIVE_ONE==daysBetween ) {
  367 + return true;
  368 + }
  369 + } else {
  370 + LocalDate today = LocalDate.now();
  371 + LocalDate localDate = DateUtils.parseDate(orderHodTime);
  372 + if ( Constant.SEVEN ==(int) ChronoUnit.DAYS.between(today, localDate) && StringUtils.isBlank(shippmentSampleConfirmResult)) {
312 373 return true;
313 374 }
314 375 }
... ... @@ -317,20 +378,27 @@ public class OrderOverTimeEventJob {
317 378  
318 379  
319 380 private Boolean filterAITEXSGSTestEvent(OrderEventJobVO eventJobVO) {
320   - int aitextestDaysBetween=0;
321   - int sgstestDaysBetween=0;
  381 + int aitextestDaysBetween = 0;
  382 + int sgstestDaysBetween = 0;
322 383 String orderHodTime = eventJobVO.getBaseInfo().getOrderHodTime();
323 384 String aitexTestFinishResult = eventJobVO.getTrackStageInfo().getAitexTestFinishResult();
324 385 String sgsTestFinishResult = eventJobVO.getTrackStageInfo().getSgsTestFinishResult();
325 386 String sgsTestFinishTime = eventJobVO.getTrackStageInfo().getSgsTestFinishTime();
326 387 String aitexTestFinishTime = eventJobVO.getTrackStageInfo().getAitexTestFinishTime();
327   - if (StringUtils.isNotBlank(orderHodTime) && StringUtils.isNotBlank(aitexTestFinishResult) && StringUtils.isNotBlank(aitexTestFinishTime)){
  388 + if (StringUtils.isNotBlank(orderHodTime) && StringUtils.isNotBlank(aitexTestFinishResult) && StringUtils.isNotBlank(aitexTestFinishTime)) {
328 389 aitextestDaysBetween = getDaysBetween(aitexTestFinishResult, aitexTestFinishTime, orderHodTime);
329 390 }
330   - if(StringUtils.isNotBlank(orderHodTime) && StringUtils.isNotBlank(sgsTestFinishResult) && StringUtils.isNotBlank(sgsTestFinishTime)){
  391 + if (StringUtils.isNotBlank(orderHodTime) && StringUtils.isNotBlank(sgsTestFinishResult) && StringUtils.isNotBlank(sgsTestFinishTime)) {
331 392 sgstestDaysBetween = getDaysBetween(sgsTestFinishResult, sgsTestFinishTime, orderHodTime);
332 393 }
333   - if (Constant.THREE == aitextestDaysBetween || Constant.THREE == sgstestDaysBetween || Constant.NEGATIVE_ONE == aitextestDaysBetween || Constant.NEGATIVE_ONE == sgstestDaysBetween ) {
  394 + if ((StringUtils.isEmpty(aitexTestFinishResult) && StringUtils.isEmpty(sgsTestFinishResult)) || (StringUtils.isEmpty(aitexTestFinishResult) && StringUtils.isEmpty(sgsTestFinishResult))){
  395 + LocalDate today = LocalDate.now();
  396 + LocalDate localDate = DateUtils.parseDate(orderHodTime);
  397 + if(Constant.THREE == (int) ChronoUnit.DAYS.between(today, localDate)){
  398 + return true;
  399 + }
  400 + }
  401 + if (Constant.THREE == aitextestDaysBetween || Constant.THREE == sgstestDaysBetween || Constant.NEGATIVE_ONE == aitextestDaysBetween || Constant.NEGATIVE_ONE == sgstestDaysBetween) {
334 402 return true;
335 403 }
336 404 return false;
... ... @@ -340,41 +408,50 @@ public class OrderOverTimeEventJob {
340 408  
341 409 private Boolean filterBarcodeArrivalEvent(OrderEventJobVO eventJobVO) {
342 410 String orderHodTime = eventJobVO.getBaseInfo().getOrderHodTime();
343   - String lastArrivalTime = eventJobVO.getTrackStageInfo().getLatestArrivalTime();
344   - if (StringUtils.isNotBlank(orderHodTime) && StringUtils.isNotBlank(lastArrivalTime) && !(lastArrivalTime.contains("ok"))) {
345   - LocalDate orderHodTimelocalDate = DateUtils.parseDate(orderHodTime);
346   - LocalDate lastArrivalTimelocalDate = DateUtils.parseDate(lastArrivalTime);
347   - if (ChronoUnit.DAYS.between(lastArrivalTimelocalDate, orderHodTimelocalDate) == Constant.SEVEN) {
  411 + LocalDate today = LocalDate.now();
  412 + LocalDate localDate = DateUtils.parseDate(orderHodTime);
  413 + if ( Constant.SEVEN ==(int) ChronoUnit.DAYS.between(today, localDate) && StringUtils.isBlank(eventJobVO.getTrackStageInfo().getLatestArrivalTime())) {
348 414 return true;
349 415 }
350   - }
351 416 return false;
352 417 }
353 418  
354 419 private Boolean filterLatestDCEvent(OrderEventJobVO eventJobVO) {
355 420 String orderHodTime = eventJobVO.getBaseInfo().getOrderHodTime();
356   - String latestBkTime = eventJobVO.getTrackStageInfo().getLatestBkTime();
357   - if (StringUtils.isNotBlank(orderHodTime) && StringUtils.isNotBlank(latestBkTime) && !(latestBkTime.contains("ok"))) {
358   - LocalDate latestBkTimelocalDate = DateUtils.parseDate(latestBkTime);
359   - LocalDate orderHodTimelocalDate = DateUtils.parseDate(orderHodTime);
360   - if (ChronoUnit.DAYS.between(latestBkTimelocalDate, orderHodTimelocalDate) == Constant.ENABLE_TEN) {
  421 + LocalDate today = LocalDate.now();
  422 + LocalDate localDate = DateUtils.parseDate(orderHodTime);
  423 + //对于A01的订单,最晚订舱日期要为12天或者6天,海运为12天,空运为6天,其他的订单为10天。 对于A01来说,不管你填写没有,也要提醒,即使你填写了,也要提醒。
  424 + if(eventJobVO.getBaseInfo().getCustomerCode().contains("A01")){
  425 + //海运
  426 + if("SEA".equals(eventJobVO.getBaseInfo().getOutboundType())){
  427 + if(Constant.FOURTEEN ==(int) ChronoUnit.DAYS.between(today, localDate)){
  428 + return true;
  429 + }
  430 + }
  431 + else if("AIR".equals(eventJobVO.getBaseInfo().getOutboundType())){
  432 + if(Constant.SEVEN ==(int) ChronoUnit.DAYS.between(today, localDate)){
  433 + return true;
  434 + }
  435 + }else{
  436 + if(Constant.ENABLE_TEN ==(int) ChronoUnit.DAYS.between(today, localDate)){
  437 + return true;
  438 + }
  439 + }
  440 + }else{
  441 + if ( Constant.ENABLE_TEN ==(int) ChronoUnit.DAYS.between(today, localDate) && StringUtils.isBlank(eventJobVO.getTrackStageInfo().getLatestBkTime())) {
361 442 return true;
362 443 }
363 444 }
364 445 return false;
365   -
366 446 }
367 447  
368 448 private Boolean filterEndCheckDateEvent(OrderEventJobVO eventJobVO) {
369 449 String orderHodTime = eventJobVO.getBaseInfo().getOrderHodTime();
370   - String endCheckApplyTime = eventJobVO.getInspectionStageInfo().getEndCheckApplyTime();
371   - if (StringUtils.isNotBlank(orderHodTime) && StringUtils.isNotBlank(endCheckApplyTime)) {
372   - LocalDate endCheckApplyTimelocalDate = DateUtils.parseDate(endCheckApplyTime);
373   - LocalDate orderHodTimelocalDate = DateUtils.parseDate(orderHodTime);
374   - if (ChronoUnit.DAYS.between(endCheckApplyTimelocalDate, orderHodTimelocalDate) == Constant.TWO) {
  450 + LocalDate today = LocalDate.now();
  451 + LocalDate localDate = DateUtils.parseDate(orderHodTime);
  452 + if ( Constant.TWO ==(int) ChronoUnit.DAYS.between(today, localDate) && StringUtils.isBlank(eventJobVO.getInspectionStageInfo().getEndCheckApplyTime())) {
375 453 return true;
376 454 }
377   - }
378 455 return false;
379 456 }
380 457  
... ... @@ -390,14 +467,14 @@ public class OrderOverTimeEventJob {
390 467 return Constant.ZERO;
391 468 }
392 469  
393   - public OrderBaseInfoVO getDateFormat(String productionDepartmentConsignTime,String orderHodTime){
  470 + public OrderBaseInfoVO getDateFormat(String productionDepartmentConsignTime, String orderHodTime) {
394 471 String substring = productionDepartmentConsignTime.substring(0, 10);
395 472 String substring1 = orderHodTime.substring(0, 10);
396 473 String productionDepartmentConsignTimeFormat = DateUtils.format(DateUtils.parseDate(substring, DATE), DateUtils.DATE);
397   - String orderHodTimeFormat = DateUtils.format(DateUtils.parseDate(substring1,DATE), DateUtils.DATE);
  474 + String orderHodTimeFormat = DateUtils.format(DateUtils.parseDate(substring1, DATE), DateUtils.DATE);
398 475 OrderBaseInfoVO orderBaseInfoVO = new OrderBaseInfoVO();
399 476 orderBaseInfoVO.setProductionDepartmentConsignTime(productionDepartmentConsignTimeFormat);
400 477 orderBaseInfoVO.setOrderHodTime(orderHodTimeFormat);
401 478 return orderBaseInfoVO;
402 479 }
403   -}
404 480 \ No newline at end of file
  481 +}
... ...
src/main/java/com/order/erp/mapper/order/OrderOpinionLogMapper.java 0 → 100644
  1 +package com.order.erp.mapper.order;
  2 +
  3 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  4 +import com.order.erp.domain.dto.order.OrderOpinionLogDO;
  5 +
  6 +public interface OrderOpinionLogMapper extends BaseMapper<OrderOpinionLogDO> {
  7 +}
... ...
src/main/java/com/order/erp/service/LocalStorageService.java
... ... @@ -3,10 +3,13 @@ package com.order.erp.service;
3 3 import com.baomidou.mybatisplus.extension.service.IService;
4 4 import com.order.erp.common.constant.ServerResult;
5 5 import com.order.erp.domain.dto.LocalStorageDO;
  6 +import com.order.erp.domain.vo.FileRespVO;
6 7 import com.order.erp.domain.vo.LocalStorageQueryVO;
7 8 import com.order.erp.domain.vo.LocalStorageVO;
8 9 import org.springframework.web.multipart.MultipartFile;
9 10  
  11 +import java.io.File;
  12 +
10 13 /**
11 14 * 本地存储(LocalStorage)表服务接口
12 15 *
... ... @@ -33,6 +36,7 @@ public interface LocalStorageService extends IService&lt;LocalStorageDO&gt; {
33 36 ServerResult uploadFileByAliOss(String name, MultipartFile file);
34 37  
35 38 ServerResult create(String name, MultipartFile file);
  39 + FileRespVO getFilePath(File file, String companyName);
36 40  
37 41 /**
38 42 * 通过ID查询单条数据
... ...
src/main/java/com/order/erp/service/admin/impl/AdminUserServiceImpl.java
... ... @@ -197,7 +197,13 @@ public class AdminUserServiceImpl extends ServiceImpl&lt;AdminUserMapper, AdminUser
197 197 if(StringUtils.isNotBlank(adminUserVO.getEmail())){
198 198 adminUserDo.setEmail(adminUserVO.getEmail());
199 199 }
  200 + List<AdminUserDO> byNickNameUserDOS = list(new LambdaQueryWrapper<AdminUserDO>().eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  201 + .eq(AdminUserDO::getUserName, adminUserVO.getNickName()));
  202 + if (CollectionUtils.isNotEmpty(byNickNameUserDOS)) {
  203 + throw new BusinessException("用户名已存在");
  204 + }
200 205 if (StringUtils.isNotBlank(adminUserVO.getNickName())) {
  206 + //后续如果根据名称找用户,使用userName比较,不要使用NickName比较。
201 207 adminUserDo.setUserName(adminUserVO.getNickName());
202 208 }
203 209 adminUserDo.setGender("男");
... ... @@ -219,7 +225,7 @@ public class AdminUserServiceImpl extends ServiceImpl&lt;AdminUserMapper, AdminUser
219 225 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
220 226 .eq(DictionaryDO::getDictName,RoleEnum.PRODUCE_USER.getName()));
221 227 if(CollectionUtils.isNotEmpty(dictionaryDOList)){
222   - Set<String> dictionaryNames = dictionaryDOList.stream().map(DictionaryDO::getDictName).collect(Collectors.toSet());
  228 + Set<String> dictionaryNames = dictionaryDOList.stream().map(DictionaryDO::getDictValue).collect(Collectors.toSet());
223 229 if(!dictionaryNames.contains(adminUserVO.getNickName())){
224 230 DictionaryVO dictionaryVO = new DictionaryVO();
225 231 dictionaryVO.setRemark("生产科");
... ... @@ -337,6 +343,9 @@ public class AdminUserServiceImpl extends ServiceImpl&lt;AdminUserMapper, AdminUser
337 343 if (RoleEnum.INSPECT_USER.getId().equals(x.getRoleId())) {
338 344 result.set(RoleEnum.INSPECT_USER);
339 345 }
  346 + if(RoleEnum.PRODUCE_USER.getId().equals(x.getRoleId())){
  347 + result.set(RoleEnum.PRODUCE_USER);
  348 + }
340 349 });
341 350 return ServerResult.success(result.get());
342 351 }
... ...
src/main/java/com/order/erp/service/impl/LocalStorageServiceImpl.java
... ... @@ -28,6 +28,7 @@ import org.springframework.stereotype.Service;
28 28 import org.springframework.web.multipart.MultipartFile;
29 29  
30 30 import java.io.File;
  31 +import java.nio.file.Files;
31 32 import java.util.List;
32 33 import java.util.Objects;
33 34  
... ... @@ -80,27 +81,49 @@ public class LocalStorageServiceImpl extends ServiceImpl&lt;LocalStorageMapper, Loc
80 81 try {
81 82 File tempFile = new File(path + "images" + File.separator + tempFileName);
82 83 if (AliOssUtil.upload(AliOssConfig.ALIYUN_BUCKET, fileName, file.getBytes())) {
83   - log.info("--------uploadByAliOss success----------");
84 84 String originImageUrl = AliOssUtil.createUrl(AliOssConfig.ALIYUN_BUCKET, fileName, new DateTime().plusYears(Constant.ENABLE_TEN).toDate());
85 85 imageRespVO.setPicUrl(originImageUrl);
86 86 // 生成缩略图
87 87 Thumbnails.of(file.getInputStream()).size(100, 100).toFile(tempFile);
88 88 if (AliOssUtil.upload(AliOssConfig.ALIYUN_BUCKET, tempFileName, FileUtil.readBytes(tempFile))) {
89   - log.info("--------uploadByAliOss 缩略图 success----------");
90 89 String thumbnailImageUrl = AliOssUtil.createUrl(AliOssConfig.ALIYUN_BUCKET, tempFileName, new DateTime().plusYears(Constant.ENABLE_TEN).toDate());
91 90 imageRespVO.setSmallPicUrl(thumbnailImageUrl);
92 91 }
93   - log.info("--------uploadByAliOss end ----------");
94 92 FileUtil.del(tempFile);
95   - log.info("--------uploadByAliOss del success ----------");
96 93 }
97 94 return ServerResult.success(imageRespVO);
98 95 } catch (Exception e) {
99   - log.error("上传图片异常:{}", e.getMessage());
  96 + log.error("上传图片异常{}", e.getMessage());
100 97 throw new BusinessException(ServerResultCode.UPLOAD_IMAGES_ERROR);
101 98 }
102 99 }
103 100  
  101 +
  102 +
  103 + public FileRespVO getFilePath(File file,String companyName) {
  104 + FileUtil.checkSize(maxSize, file.length()); // 使用文件长度检查大小
  105 + String fileName = AliOssUtil.getUniqueFileName(companyName+"生产指示书.pdf");
  106 + String tempFileName = "Thumbnails" + Constant.CROSS_BAR_CHARACTER + fileName;
  107 + FileRespVO fileRespVO = new FileRespVO();
  108 + try {
  109 + // 文件路径生成(如果需要保存临时文件)
  110 + File tempFile = new File(path + "files" + File.separator + tempFileName);
  111 +
  112 + // 使用文件的字节数组上传到阿里云 OSS
  113 + byte[] fileBytes = Files.readAllBytes(file.toPath()); // 将 File 转换为字节数组
  114 + if (AliOssUtil.upload(AliOssConfig.ALIYUN_BUCKET, fileName, fileBytes)) {
  115 + String fileUrl = AliOssUtil.createUrl(AliOssConfig.ALIYUN_BUCKET, fileName, new DateTime().plusYears(Constant.ENABLE_TEN).toDate());
  116 + fileRespVO.setFileUrl(fileUrl);
  117 + FileUtil.del(tempFile); // 删除临时文件
  118 + }
  119 + return fileRespVO;
  120 + } catch (Exception e) {
  121 + log.error("上传文件异常:{}", e.getMessage());
  122 + throw new BusinessException(ServerResultCode.UPLOAD_IMAGES_ERROR);
  123 + }
  124 + }
  125 +
  126 +
104 127 @Override
105 128 public ServerResult create(String name, MultipartFile multipartFile) {
106 129 FileUtil.checkSize(maxSize, multipartFile.getSize());
... ... @@ -127,6 +150,7 @@ public class LocalStorageServiceImpl extends ServiceImpl&lt;LocalStorageMapper, Loc
127 150 }
128 151 }
129 152  
  153 +
130 154 /**
131 155 * 通过ID查询单条数据
132 156 * <p>
... ...
src/main/java/com/order/erp/service/order/OrderBaseInfoService.java
... ... @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
5 5 import com.order.erp.common.constant.ServerResult;
6 6 import com.order.erp.common.excel4j.exceptions.Excel4JException;
7 7 import com.order.erp.domain.dto.order.OrderBaseInfoDO;
  8 +import com.order.erp.domain.vo.ProducePdfVO;
8 9 import com.order.erp.domain.vo.order.*;
9 10 import freemarker.template.TemplateException;
10 11  
... ... @@ -100,6 +101,9 @@ public interface OrderBaseInfoService extends IService&lt;OrderBaseInfoDO&gt; {
100 101 * @return 是否成功
101 102 */
102 103 ServerResult deleteById(OrderBaseInfoQueryVO orderBaseInfoQueryVO);
  104 + ServerResult passRate(OrderOpinionLogVO orderOpinionLogVO);
  105 +
  106 + ServerResult produceReport(ProducePdfVO producePdfVO);
103 107  
104 108  
105 109 long countByOrderStatus(Integer orderFinish);
... ... @@ -113,8 +117,10 @@ public interface OrderBaseInfoService extends IService&lt;OrderBaseInfoDO&gt; {
113 117  
114 118 long countRecentYear();
115 119  
116   - ServerResult checkChargeOrderCount(List<Long> orderIds);
  120 + ServerResult checkChargeOrderCount(OrderBaseInfoVO baseInfoVO);
117 121  
118 122 List<OrderBaseInfoDO> getEventList();
119 123  
  124 + ServerResult send(ProducePdfVO producePdfVO) throws Exception;
  125 +
120 126 }
... ...
src/main/java/com/order/erp/service/order/OrderOpinionLogService.java 0 → 100644
  1 +package com.order.erp.service.order;
  2 +
  3 +import com.baomidou.mybatisplus.extension.service.IService;
  4 +import com.order.erp.common.constant.ServerResult;
  5 +import com.order.erp.domain.dto.order.OrderOpinionLogDO;
  6 +import com.order.erp.domain.vo.order.OrderOpinionLogVO;
  7 +
  8 +public interface OrderOpinionLogService extends IService<OrderOpinionLogDO> {
  9 +
  10 + ServerResult queryById(OrderOpinionLogVO orderOpinionLogVo);
  11 +}
... ...
src/main/java/com/order/erp/service/order/impl/OrderBaseInfoServiceImpl.java
... ... @@ -3,7 +3,9 @@ package com.order.erp.service.order.impl;
3 3 import cn.hutool.core.bean.BeanUtil;
4 4 import cn.hutool.core.collection.CollUtil;
5 5 import cn.hutool.core.collection.CollectionUtil;
  6 +import com.alibaba.fastjson.JSON;
6 7 import com.alibaba.fastjson.JSONObject;
  8 +import com.alibaba.fastjson.TypeReference;
7 9 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
8 10 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
9 11 import com.baomidou.mybatisplus.core.metadata.IPage;
... ... @@ -25,11 +27,14 @@ import com.order.erp.domain.*;
25 27 import com.order.erp.domain.dto.BaseDO;
26 28 import com.order.erp.domain.dto.SystemSettingDO;
27 29 import com.order.erp.domain.dto.admin.AdminUserDO;
  30 +import com.order.erp.domain.dto.admin.AdminUserRoleDO;
28 31 import com.order.erp.domain.dto.order.*;
  32 +import com.order.erp.domain.vo.ProducePdfVO;
29 33 import com.order.erp.domain.vo.order.*;
30 34 import com.order.erp.job.OrderOverTimeEventJob;
31 35 import com.order.erp.mapper.order.OrderBaseInfoMapper;
32 36 import com.order.erp.service.SystemSettingService;
  37 +import com.order.erp.service.admin.AdminUserRoleService;
33 38 import com.order.erp.service.admin.AdminUserService;
34 39 import com.order.erp.service.order.*;
35 40 import freemarker.template.TemplateException;
... ... @@ -43,14 +48,18 @@ import org.springframework.transaction.annotation.Transactional;
43 48 import javax.annotation.Resource;
44 49 import javax.mail.MessagingException;
45 50 import javax.servlet.http.HttpServletResponse;
  51 +import java.io.File;
46 52 import java.io.IOException;
47 53 import java.io.InputStream;
48 54 import java.math.BigDecimal;
49 55 import java.math.RoundingMode;
50 56 import java.net.URL;
51 57 import java.text.DecimalFormat;
  58 +import java.time.LocalDate;
52 59 import java.time.LocalDateTime;
  60 +import java.time.Month;
53 61 import java.util.*;
  62 +import java.util.concurrent.TimeUnit;
54 63 import java.util.function.Function;
55 64 import java.util.stream.Collectors;
56 65  
... ... @@ -118,6 +127,20 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
118 127 @Resource
119 128 private EmailSendUtils emailSendUtils;
120 129  
  130 + @Resource
  131 + private OrderOpinionLogService orderOpinionLogService;
  132 + @Resource
  133 + private RedisUtils redisUtils;
  134 + @Resource
  135 + private EasyPdfUtils pdfUtils;
  136 +
  137 + @Resource
  138 + private AdminUserService adminUserService;
  139 +
  140 + @Resource
  141 + private ReceiveEmailMappingService receiveEmailMappingService;
  142 + @Resource
  143 + private AdminUserRoleService adminUserRoleService;
121 144  
122 145  
123 146 /**
... ... @@ -232,6 +255,12 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
232 255  
233 256 if (CollectionUtils.isNotEmpty(orderBaseInfoDOList)) {
234 257 List<OrderInfoResultVO> resultVOList = orderBaseInfoDOList.stream().map(x -> {
  258 + //在导出时只导出产品意见的最后一行。
  259 + if(x.getProductionComment().contains("\n")){
  260 + String[] productionCommentS = x.getProductionComment().split("\n");
  261 + String productionComment = productionCommentS[productionCommentS.length - 1];
  262 + x.setProductionComment(productionComment);
  263 + }
235 264 OrderInfoResultVO resultVO = new OrderInfoResultVO();
236 265 BeanUtils.copyProperties(x, resultVO);
237 266 return resultVO;
... ... @@ -342,7 +371,7 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
342 371 }
343 372 if (StringUtils.isNotBlank(baseFields.getProductionComment()) &&
344 373 OrderLockFieldEnum.SELECTED.getStatus().equals(baseFields.getProductionComment())) {
345   - map.put("生产要求", orderInfoResultVO.getProductionComment());
  374 + map.put("产品意见", orderInfoResultVO.getProductionComment());
346 375 }
347 376 if (StringUtils.isNotBlank(baseFields.getOrderCount()) &&
348 377 OrderLockFieldEnum.SELECTED.getStatus().equals(baseFields.getOrderCount())) {
... ... @@ -881,7 +910,7 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
881 910 if (CollectionUtils.isEmpty(trackStageDOS)) {
882 911 return;
883 912 }
884   - Map<Long, OrderTrackStageDO> trackStageDOMap = trackStageDOS.stream().collect(Collectors.toMap(OrderTrackStageDO::getOrderId, Function.identity()));
  913 + Map<Long, OrderTrackStageDO> trackStageDOMap = trackStageDOS.stream().collect(Collectors.toMap(OrderTrackStageDO::getOrderId, Function.identity(),(existing, replacement) -> existing));
885 914 orderInfoResultVOList.forEach(result -> {
886 915 if (trackStageDOMap.containsKey(result.getId())) {
887 916 OrderTrackStageDO trackStageDO = trackStageDOMap.get(result.getId());
... ... @@ -1234,7 +1263,7 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1234 1263 if (CollectionUtils.isEmpty(inspectionStageDOS)) {
1235 1264 return;
1236 1265 }
1237   - Map<Long, OrderInspectionStageDO> inspectionStageDOMap = inspectionStageDOS.stream().collect(Collectors.toMap(OrderInspectionStageDO::getOrderId, Function.identity()));
  1266 + Map<Long, OrderInspectionStageDO> inspectionStageDOMap = inspectionStageDOS.stream().collect(Collectors.toMap(OrderInspectionStageDO::getOrderId, Function.identity(),(existing, replacement) -> existing));
1238 1267 orderInfoResultVOList.forEach(result -> {
1239 1268 if (inspectionStageDOMap.containsKey(result.getId())) {
1240 1269 OrderInspectionStageDO inspectionStageDO = inspectionStageDOMap.get(result.getId());
... ... @@ -1261,7 +1290,7 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1261 1290 queryVO.setBusinessPerson(Arrays.asList(dataScope.getUser().getNickName()));
1262 1291 }
1263 1292 // 生产科
1264   - if(Objects.nonNull(roleEnum) && roleEnum.getId().equals(RoleEnum.PRODUCE_USER.getId())){
  1293 + if (Objects.nonNull(roleEnum) && roleEnum.getId().equals(RoleEnum.PRODUCE_USER.getId())) {
1265 1294 queryVO.setProductionDepartment(Arrays.asList(dataScope.getUser().getNickName()));
1266 1295 }
1267 1296 if (StringUtils.isNotBlank(queryVO.getCommitUserPhone())) {
... ... @@ -1430,11 +1459,29 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1430 1459 if (Objects.isNull(baseInfoVO)) {
1431 1460 throw new BusinessException(ServerResultCode.ORDER_BASE_INFO_EMPTY);
1432 1461 }
  1462 + LocalDate currentDate = LocalDate.now();
  1463 + Month month = currentDate.getMonth();
  1464 + int currentMonth = month.getValue();
  1465 + int dayOfMonth = currentDate.getDayOfMonth();
  1466 + String originProductionComment = baseInfoVO.getProductionComment();
  1467 + if (StringUtils.isNotBlank(baseInfoVO.getProductionComment())) {
  1468 + String date = currentMonth + "/" + dayOfMonth + ": ";
  1469 + String productionComment = baseInfoVO.getProductionComment();
  1470 + productionComment = date + productionComment;
  1471 + baseInfoVO.setProductionComment(productionComment);
  1472 +
  1473 + }
1433 1474 Long userId = dataScope.getLoginUserId();
1434 1475 OrderBaseInfoDO baseInfoDO = new OrderBaseInfoDO();
1435 1476 BeanUtils.copyProperties(baseInfoVO, baseInfoDO);
1436 1477 baseInfoDO.setOrderStatus(OrderStatusEnum.CREATE_FINISH.getStatus());
1437 1478 save(baseInfoDO);
  1479 +
  1480 + OrderOpinionLogDO orderOpinionLogDO = buildOrderOpinionLogDo(baseInfoDO.getId(),
  1481 + OrderOpinionLogEnum.ORDER_PRODUCTION_COMMENT.getDesc(),
  1482 + originProductionComment);
  1483 + orderOpinionLogService.save(orderOpinionLogDO);
  1484 +
1438 1485 OrderTrackStageDO orderTrackStageDO = new OrderTrackStageDO();
1439 1486 orderTrackStageDO.setOrderId(baseInfoDO.getId());
1440 1487 orderTrackStageDO.setOrderStatus(OrderStatusEnum.CREATE_FINISH.getStatus());
... ... @@ -1507,8 +1554,9 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1507 1554 return OrderOptLogDO.builder().orderId(orderId).userId(userId).fields(jsonString).optType(optType).build();
1508 1555 }
1509 1556  
1510   -
1511   -
  1557 + private OrderOpinionLogDO buildOrderOpinionLogDo(Long orderId, String type, String field) {
  1558 + return OrderOpinionLogDO.builder().orderId(orderId).opinionType(type).field(field).build();
  1559 + }
1512 1560 /**
1513 1561 * @param updateVO
1514 1562 */
... ... @@ -1597,14 +1645,48 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1597 1645 if (Objects.isNull(orderBaseInfoDo)) {
1598 1646 throw new BusinessException(ServerResultCode.ORDER_BASE_INFO_EMPTY);
1599 1647 }
  1648 + LocalDate currentDate = LocalDate.now();
  1649 + Month month = currentDate.getMonth();
  1650 + int currentMonth = month.getValue();
  1651 + int dayOfMonth = currentDate.getDayOfMonth();
1600 1652 OrderOptLogDO optLogDO = new OrderOptLogDO();
  1653 + List<OrderOpinionLogDO> orderOpinionLogDOList = new ArrayList<>();
1601 1654 if (Objects.nonNull(updateVO.getBaseInfo())) {
1602   -
  1655 + //用户编辑时,产品意见与这个订单的上一次产品意见内容不一样。
  1656 + if (StringUtils.isNotBlank(updateVO.getBaseInfo().getProductionComment()) && !(updateVO.getBaseInfo().getProductionComment().equals(orderBaseInfoDo.getProductionComment()))) {
  1657 + //说明用户第一次填写产品意见,这一步其实没必要,因为在add中会添加。
  1658 + if (org.apache.commons.lang3.StringUtils.isEmpty(orderBaseInfoDo.getProductionComment())) {
  1659 + OrderOpinionLogDO orderOpinionLogDO = buildOrderOpinionLogDo(updateVO.getOrderId(), OrderOpinionLogEnum.ORDER_PRODUCTION_COMMENT.getDesc(), updateVO.getBaseInfo().getProductionComment());
  1660 + orderOpinionLogDOList.add(orderOpinionLogDO);
  1661 + } else {
  1662 + //说明用户不是第一次填写产品意见,并且填写的内容与上一次的产品意见不一样。
  1663 + String[] parts = updateVO.getBaseInfo().getProductionComment().split("\n");
  1664 + //取最后一条的数据。
  1665 + String lastPart = parts[parts.length - 1].trim();
  1666 + OrderOpinionLogDO orderOpinionLogDO = buildOrderOpinionLogDo(updateVO.getOrderId(), OrderOpinionLogEnum.ORDER_PRODUCTION_COMMENT.getDesc(), lastPart);
  1667 + orderOpinionLogDOList.add(orderOpinionLogDO);
  1668 + }
  1669 + String date = currentMonth + "/" + dayOfMonth;
  1670 + String productionComment = orderBaseInfoDo.getProductionComment();
  1671 + StringBuilder stringBuilder = new StringBuilder(productionComment);
  1672 + String[] newProductionComment = updateVO.getBaseInfo().getProductionComment().split("\n");
  1673 + //对于四个结果,并且当前输入产品意见文字小于上一次的产品意见后续填写不需要换行。
  1674 + if((!newProductionComment[newProductionComment.length - 1].trim().contains("确认通过") &&
  1675 + !newProductionComment[newProductionComment.length - 1].trim().contains("确认未通过")) && updateVO.getBaseInfo().getProductionComment().length() > orderBaseInfoDo.getProductionComment().length()){
  1676 + stringBuilder.append("\n").append(date + ": " + newProductionComment[newProductionComment.length - 1].trim());
  1677 + updateVO.getBaseInfo().setProductionComment(stringBuilder.toString());
  1678 + sendProductionCommentEmail(orderBaseInfoDo, stringBuilder.toString());
  1679 + }else{
  1680 + sendProductionCommentEmail(orderBaseInfoDo,updateVO.getBaseInfo().getProductionComment());
  1681 + }
  1682 + }
1603 1683 buildUpdateVO(updateVO.getBaseInfo(), orderBaseInfoDo);
1604 1684 orderBaseInfoDo.setId(updateVO.getOrderId());
1605 1685 optLogDO = buildOrderOptLogDo(updateVO.getOrderId(), userId, OrderOptTypeEnum.ORDER_EDIT.getDesc(), JSONObject.toJSONString(updateVO));
1606 1686 clearLockedField(updateVO.getOrderId(), userId, LockedFieldTypeEnum.ORDER_BASE);
1607 1687 }
  1688 +
  1689 +
1608 1690 if (Objects.nonNull(updateVO.getProfitAnalysisInfo())) {
1609 1691 checkApply(updateVO.getOrderId(), userId, ApplyTypeEnum.ORDER_PROFIT_APPLY);
1610 1692 OrderFieldLockApplyDO orderFieldLockApplyDO = handlerProfitRate(updateVO.getProfitAnalysisInfo(), orderBaseInfoDo, userId);
... ... @@ -1635,7 +1717,23 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1635 1717 trackStageDO.setPpTime(trackStageInfo.getPpTime());
1636 1718 }
1637 1719 if (StringUtils.isNotBlank(trackStageInfo.getPpConfirmResult())) {
  1720 + if (!(trackStageInfo.getPpConfirmResult().equals(trackStageDO.getPpConfirmResult()))) {
  1721 + String resultText = trackStageInfo.getPpConfirmResult().contains("ok")
  1722 + ? "PP样品确认通过"
  1723 + : "PP样品确认未通过";
  1724 + //用于在跟单记录中展示。
  1725 + OrderOpinionLogDO orderOpinionLogDO = buildOrderOpinionLogDo(updateVO.getOrderId(), OrderOpinionLogEnum.ORDER_PP_CONFIRRM_RESULT.getDesc(), trackStageInfo.getPpConfirmResult());
  1726 + orderOpinionLogDOList.add(orderOpinionLogDO);
  1727 + //添加到产品意见中去。
  1728 + String date = currentMonth + "/" + dayOfMonth;
  1729 + String productionComment = orderBaseInfoDo.getProductionComment();
  1730 + StringBuilder stringBuilder = new StringBuilder(productionComment);
  1731 + stringBuilder.append("\n").append(date + ":" + resultText);
  1732 + orderBaseInfoDo.setProductionComment(stringBuilder.toString());
  1733 +// sendProductionCommentEmail(orderBaseInfoDo, stringBuilder.toString());
  1734 + setEmailSendUtilsRedis(orderBaseInfoDo,resultText,stringBuilder.toString());
1638 1735  
  1736 + }
1639 1737 trackStageDO.setPpConfirmResult(trackStageInfo.getPpConfirmResult());
1640 1738 }
1641 1739 if (StringUtils.isNotBlank(trackStageInfo.getEsoSampleSendTime())) {
... ... @@ -1645,7 +1743,22 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1645 1743 trackStageDO.setShippmentSampleSendTime(trackStageInfo.getShippmentSampleSendTime());
1646 1744 }
1647 1745 if (StringUtils.isNotBlank(trackStageInfo.getShippmentSampleConfirmResult())) {
1648   - trackStageDO.setShippmentSampleConfirmResult(trackStageInfo.getShippmentSampleConfirmResult());
  1746 + if (!(trackStageInfo.getShippmentSampleConfirmResult().equals(trackStageDO.getShippmentSampleConfirmResult()))) {
  1747 + String resultText = trackStageInfo.getShippmentSampleConfirmResult().contains("ok")
  1748 + ? "大货样确认通过"
  1749 + : "大货样确认未通过";
  1750 + OrderOpinionLogDO orderOpinionLogDO = buildOrderOpinionLogDo(updateVO.getOrderId(), OrderOpinionLogEnum.ORDER_SHIPMENT_SAMPLE_CONFIRM_RESULT.getDesc(), trackStageInfo.getShippmentSampleConfirmResult());
  1751 + orderOpinionLogDOList.add(orderOpinionLogDO);
  1752 + //添加到产品意见中去。
  1753 + String date = currentMonth + "/" + dayOfMonth;
  1754 + String productionComment = orderBaseInfoDo.getProductionComment();
  1755 + StringBuilder stringBuilder = new StringBuilder(productionComment);
  1756 + stringBuilder.append("\n").append(date + ": " + resultText);
  1757 + orderBaseInfoDo.setProductionComment(stringBuilder.toString());
  1758 +// sendProductionCommentEmail(orderBaseInfoDo, stringBuilder.toString());
  1759 + setEmailSendUtilsRedis(orderBaseInfoDo,resultText,stringBuilder.toString());
  1760 + }
  1761 + trackStageDO.setShippmentSampleConfirmResult(trackStageInfo.getShippmentSampleConfirmResult());
1649 1762 }
1650 1763 if (StringUtils.isNotBlank(trackStageInfo.getSelfTestPassTime())) {
1651 1764 trackStageDO.setSelfTestPassTime(trackStageInfo.getSelfTestPassTime());
... ... @@ -1654,13 +1767,42 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1654 1767 trackStageDO.setAitexTestSendTime(trackStageInfo.getAitexTestSendTime());
1655 1768 }
1656 1769 if (StringUtils.isNotBlank(trackStageInfo.getAitexTestFinishResult())) {
1657   -
  1770 + if (!(trackStageInfo.getAitexTestFinishResult().equals(trackStageDO.getAitexTestFinishResult()))) {
  1771 + String resultText = trackStageInfo.getAitexTestFinishResult().contains("ok")
  1772 + ? "Aitex测试确认通过"
  1773 + : "Aitex测试确认未通过";
  1774 + OrderOpinionLogDO orderOpinionLogDO = buildOrderOpinionLogDo(updateVO.getOrderId(), OrderOpinionLogEnum.ORDER_AITEX_TEST_FINISH_RESULT.getDesc(), trackStageInfo.getAitexTestFinishResult());
  1775 + orderOpinionLogDOList.add(orderOpinionLogDO);
  1776 + //添加到产品意见中去。
  1777 + String date = currentMonth + "/" + dayOfMonth;
  1778 + String productionComment = orderBaseInfoDo.getProductionComment();
  1779 + StringBuilder stringBuilder = new StringBuilder(productionComment);
  1780 + stringBuilder.append("\n").append(date + ": " + resultText);
  1781 + orderBaseInfoDo.setProductionComment(stringBuilder.toString());
  1782 +// sendProductionCommentEmail(orderBaseInfoDo, stringBuilder.toString());
  1783 + setEmailSendUtilsRedis(orderBaseInfoDo,resultText,stringBuilder.toString());
  1784 + }
1658 1785 trackStageDO.setAitexTestFinishResult(trackStageInfo.getAitexTestFinishResult());
1659 1786 }
1660 1787 if (StringUtils.isNotBlank(trackStageInfo.getSgsTestSendTime())) {
1661 1788 trackStageDO.setSgsTestSendTime(trackStageInfo.getSgsTestSendTime());
1662 1789 }
1663 1790 if (StringUtils.isNotBlank(trackStageInfo.getSgsTestFinishResult())) {
  1791 + if (!(trackStageInfo.getSgsTestFinishResult().equals(trackStageDO.getSgsTestFinishResult()))) {
  1792 + String resultText = trackStageInfo.getSgsTestFinishResult().contains("ok")
  1793 + ? "SGS测试确认通过"
  1794 + : "SGS测试确认未通过";
  1795 + OrderOpinionLogDO orderOpinionLogDO = buildOrderOpinionLogDo(updateVO.getOrderId(), OrderOpinionLogEnum.ORDER_SGS_TEST_FINISH_RESULT.getDesc(), trackStageInfo.getSgsTestFinishResult());
  1796 + orderOpinionLogDOList.add(orderOpinionLogDO);
  1797 + //添加到产品意见中去。
  1798 + String date = currentMonth + "/" + dayOfMonth;
  1799 + String productionComment = orderBaseInfoDo.getProductionComment();
  1800 + StringBuilder stringBuilder = new StringBuilder(productionComment);
  1801 + stringBuilder.append("\n").append(date + ": " + resultText);
  1802 + orderBaseInfoDo.setProductionComment(stringBuilder.toString());
  1803 +// sendProductionCommentEmail(orderBaseInfoDo, stringBuilder.toString());
  1804 + setEmailSendUtilsRedis(orderBaseInfoDo,resultText,stringBuilder.toString());
  1805 + }
1664 1806  
1665 1807 trackStageDO.setSgsTestFinishResult(trackStageInfo.getSgsTestFinishResult());
1666 1808 }
... ... @@ -1694,6 +1836,62 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1694 1836 trackStageDO.setOrderId(updateVO.getOrderId());
1695 1837 trackStageDO.setOrderStatus(OrderStatusEnum.TRACK_ING.getStatus());
1696 1838 trackStageService.save(trackStageDO);
  1839 + if(StringUtils.isNotBlank(updateVO.getTrackStageInfo().getPpConfirmResult())){
  1840 + String resultText = updateVO.getTrackStageInfo().getPpConfirmResult().contains("ok")
  1841 + ? "PP样品确认通过"
  1842 + : "PP样品确认未通过";
  1843 + OrderOpinionLogDO orderOpinionLogDO =buildOrderOpinionLogDo(updateVO.getOrderId(),OrderOpinionLogEnum.ORDER_PP_CONFIRRM_RESULT.getDesc(),trackStageInfo.getPpConfirmResult());
  1844 + orderOpinionLogDOList.add(orderOpinionLogDO);
  1845 + String date=currentMonth+"/"+dayOfMonth;
  1846 + String productionComment = orderBaseInfoDo.getProductionComment();
  1847 + StringBuilder stringBuilder = new StringBuilder(productionComment);
  1848 + stringBuilder.append("\n").append(date+": "+resultText);
  1849 + orderBaseInfoDo.setProductionComment(stringBuilder.toString());
  1850 +// sendProductionCommentEmail(orderBaseInfoDo,stringBuilder.toString());
  1851 + setEmailSendUtilsRedis(orderBaseInfoDo,resultText,stringBuilder.toString());
  1852 + }
  1853 + if(StringUtils.isNotBlank(updateVO.getTrackStageInfo().getShippmentSampleConfirmResult())) {
  1854 + String resultText = updateVO.getTrackStageInfo().getShippmentSampleConfirmResult().contains("ok")
  1855 + ? "大货样确认通过"
  1856 + : "大货样确认未通过";
  1857 + OrderOpinionLogDO orderOpinionLogDO = buildOrderOpinionLogDo(updateVO.getOrderId(), OrderOpinionLogEnum.ORDER_SHIPMENT_SAMPLE_CONFIRM_RESULT.getDesc(), trackStageInfo.getShippmentSampleConfirmResult());
  1858 + orderOpinionLogDOList.add(orderOpinionLogDO);
  1859 + String date=currentMonth+"/"+dayOfMonth;
  1860 + String productionComment = orderBaseInfoDo.getProductionComment();
  1861 + StringBuilder stringBuilder = new StringBuilder(productionComment);
  1862 + stringBuilder.append("\n").append(date+": "+resultText);
  1863 + orderBaseInfoDo.setProductionComment(stringBuilder.toString());
  1864 +// sendProductionCommentEmail(orderBaseInfoDo,stringBuilder.toString());
  1865 + setEmailSendUtilsRedis(orderBaseInfoDo,resultText,stringBuilder.toString());
  1866 + }
  1867 + if(StringUtils.isNotBlank(updateVO.getTrackStageInfo().getAitexTestFinishResult())){
  1868 + String resultText =updateVO.getTrackStageInfo().getAitexTestFinishResult().contains("ok")
  1869 + ? "Aitex测试确认通过"
  1870 + : "Aitex测试确认未通过";
  1871 + OrderOpinionLogDO orderOpinionLogDO =buildOrderOpinionLogDo(updateVO.getOrderId(),OrderOpinionLogEnum.ORDER_AITEX_TEST_FINISH_RESULT.getDesc(),trackStageInfo.getAitexTestFinishResult());
  1872 + orderOpinionLogDOList.add(orderOpinionLogDO);
  1873 + String date=currentMonth+"/"+dayOfMonth;
  1874 + String productionComment = orderBaseInfoDo.getProductionComment();
  1875 + StringBuilder stringBuilder = new StringBuilder(productionComment);
  1876 + stringBuilder.append("\n").append(date+": "+resultText);
  1877 + orderBaseInfoDo.setProductionComment(stringBuilder.toString());
  1878 +// sendProductionCommentEmail(orderBaseInfoDo,stringBuilder.toString());
  1879 + setEmailSendUtilsRedis(orderBaseInfoDo,resultText,stringBuilder.toString());
  1880 + }
  1881 + if(StringUtils.isNotBlank(updateVO.getTrackStageInfo().getSgsTestFinishResult())){
  1882 + String resultText = updateVO.getTrackStageInfo().getSgsTestFinishResult().contains("ok")
  1883 + ? "SGS测试确认通过"
  1884 + : "SGS测试确认未通过";
  1885 + OrderOpinionLogDO orderOpinionLogDO =buildOrderOpinionLogDo(updateVO.getOrderId(),OrderOpinionLogEnum.ORDER_SGS_TEST_FINISH_RESULT.getDesc(),trackStageInfo.getSgsTestFinishResult());
  1886 + orderOpinionLogDOList.add(orderOpinionLogDO);
  1887 + String date=currentMonth+"/"+dayOfMonth;
  1888 + String productionComment = orderBaseInfoDo.getProductionComment();
  1889 + StringBuilder stringBuilder = new StringBuilder(productionComment);
  1890 + stringBuilder.append("\n").append(date+": "+resultText);
  1891 + orderBaseInfoDo.setProductionComment(stringBuilder.toString());
  1892 +// sendProductionCommentEmail(orderBaseInfoDo,stringBuilder.toString());
  1893 + setEmailSendUtilsRedis(orderBaseInfoDo,resultText,stringBuilder.toString());
  1894 + }
1697 1895 }
1698 1896 orderBaseInfoDo.setOrderStatus(OrderStatusEnum.TRACK_ING.getStatus());
1699 1897 optLogDO = buildOrderOptLogDo(updateVO.getOrderId(), userId, OrderOptTypeEnum.ORDER_TRACKER_EDIT_APPLY.getDesc(), JSONObject.toJSONString(updateVO));
... ... @@ -1705,11 +1903,11 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1705 1903 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
1706 1904 .eq(OrderInspectionStageDO::getOrderId, updateVO.getOrderId()));
1707 1905 OrderInspectionStageVO inspectionStageInfo = updateVO.getInspectionStageInfo();
1708   - String midCheckResult=inspectionStageInfo.getMidCheckResult();
1709   - String endCheckResult=inspectionStageInfo.getEndCheckResult();
  1906 + String midCheckResult = inspectionStageInfo.getMidCheckResult();
  1907 + String endCheckResult = inspectionStageInfo.getEndCheckResult();
1710 1908 if (Objects.nonNull(inspectionStageDO)) {
1711   - midCheckResult=inspectionStageDO.getMidCheckResult();
1712   - endCheckResult=inspectionStageDO.getEndCheckResult();
  1909 + midCheckResult = inspectionStageDO.getMidCheckResult();
  1910 + endCheckResult = inspectionStageDO.getEndCheckResult();
1713 1911 if (StringUtils.isNotBlank(inspectionStageInfo.getMidCheckApplyTime())) {
1714 1912 inspectionStageDO.setMidCheckApplyTime(inspectionStageInfo.getMidCheckApplyTime());
1715 1913 }
... ... @@ -1753,8 +1951,8 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1753 1951 AdminUserDO ProductionDepartmentUserDO = userService.getOne(new LambdaQueryWrapper<AdminUserDO>()
1754 1952 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
1755 1953 .eq(AdminUserDO::getUserName, orderBaseInfoDO.getProductionDepartment()));
1756   - if( Objects.nonNull(ProductionDepartmentUserDO) && StringUtils.isNotBlank(ProductionDepartmentUserDO.getEmail())){
1757   - sendOrderInspectionStage(updateVO,midCheckResult,endCheckResult);
  1954 + if (Objects.nonNull(ProductionDepartmentUserDO) && StringUtils.isNotBlank(ProductionDepartmentUserDO.getEmail())) {
  1955 + sendOrderInspectionStage(updateVO, midCheckResult, endCheckResult);
1758 1956 }
1759 1957 } else {
1760 1958 inspectionStageDO = new OrderInspectionStageDO();
... ... @@ -1766,10 +1964,10 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1766 1964 AdminUserDO ProductionDepartmentUserDO = userService.getOne(new LambdaQueryWrapper<AdminUserDO>()
1767 1965 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
1768 1966 .eq(AdminUserDO::getUserName, orderBaseInfoDO.getProductionDepartment()));
1769   - if( Objects.nonNull(ProductionDepartmentUserDO) && StringUtils.isNotBlank(ProductionDepartmentUserDO.getEmail())){
1770   - midCheckResult="1";
1771   - endCheckResult="1";
1772   - sendOrderInspectionStage(updateVO,midCheckResult,endCheckResult);
  1967 + if (Objects.nonNull(ProductionDepartmentUserDO) && StringUtils.isNotBlank(ProductionDepartmentUserDO.getEmail())) {
  1968 + midCheckResult = "1";
  1969 + endCheckResult = "1";
  1970 + sendOrderInspectionStage(updateVO, midCheckResult, endCheckResult);
1773 1971 }
1774 1972  
1775 1973 }
... ... @@ -1779,9 +1977,16 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1779 1977 }
1780 1978 updateById(orderBaseInfoDo);
1781 1979 orderOptLogService.save(optLogDO);
  1980 + orderOpinionLogService.saveBatch(orderOpinionLogDOList);
1782 1981 return ServerResult.success();
1783 1982 }
1784   -
  1983 +//这个方法的作用就是:她们反应对于内部编号相同的订单,就不需要发送四个测试结果的产品意见信息,不然创建一个订单就发送四个测试结果,太麻烦了,所以这里根据项目号和测试结果进行区分。
  1984 + public void setEmailSendUtilsRedis(OrderBaseInfoDO orderBaseInfoDo,String resultText,String productionComment){
  1985 + if(!redisUtils.hasKey(orderBaseInfoDo.getInnerNo()+Constant.CROSS_BAR_CHARACTER+resultText)){
  1986 + sendProductionCommentEmail(orderBaseInfoDo,productionComment);
  1987 + redisUtils.set(orderBaseInfoDo.getInnerNo()+Constant.CROSS_BAR_CHARACTER+resultText, "1", 90, TimeUnit.DAYS);
  1988 + }
  1989 + }
1785 1990 /**
1786 1991 * @param orderId
1787 1992 * @param userId
... ... @@ -1864,7 +2069,7 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1864 2069 }
1865 2070 if (Objects.nonNull(baseInfoVO.getOrderCount())) {
1866 2071 baseInfoDO.setOrderCount(baseInfoVO.getOrderCount());
1867   - checkChargeOrderCount(Arrays.asList(baseInfoVO.getId()));
  2072 + checkChargeOrderCount(baseInfoVO);
1868 2073 }
1869 2074 if (StringUtils.isNotBlank(baseInfoVO.getOrderComposition())) {
1870 2075 baseInfoDO.setOrderComposition(baseInfoVO.getOrderComposition());
... ... @@ -1887,6 +2092,9 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1887 2092 if (StringUtils.isNotBlank(baseInfoVO.getBusinessPerson())) {
1888 2093 baseInfoDO.setBusinessPerson(baseInfoVO.getBusinessPerson());
1889 2094 }
  2095 + if (Objects.nonNull(baseInfoVO.getReturnOrder())){
  2096 + baseInfoDO.setReturnOrder(baseInfoVO.getReturnOrder());
  2097 + }
1890 2098 }
1891 2099  
1892 2100 /**
... ... @@ -1954,7 +2162,78 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1954 2162 * @return
1955 2163 */
1956 2164  
  2165 + @Override
  2166 + public ServerResult passRate(OrderOpinionLogVO orderOpinionLogVO) {
  2167 + if (CollectionUtils.isEmpty(orderOpinionLogVO.getIds())) {
  2168 + return ServerResult.fail("OrderId 参数不能为空");
  2169 + }
  2170 + //过滤掉返单的数据。
  2171 + List<OrderBaseInfoDO> orderBaseInfoDOList = baseInfoService.list(new LambdaQueryWrapper<OrderBaseInfoDO>()
  2172 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  2173 + .in(OrderBaseInfoDO::getId, orderOpinionLogVO.getIds())
  2174 + .and(wrapper -> wrapper.ne(OrderBaseInfoDO::getReturnOrder, Constant.STRING_ONE).or().isNull(OrderBaseInfoDO::getReturnOrder)));
  2175 + List<Long> orderBaseInfoList = orderBaseInfoDOList.stream().map(OrderBaseInfoDO::getId).filter(Objects::nonNull).collect(Collectors.toList());
  2176 + //过滤完返单的数据。
  2177 + if(CollectionUtils.isNotEmpty(orderBaseInfoList)){
  2178 + LambdaQueryWrapper<OrderOpinionLogDO> orderOpinionWrapper = new LambdaQueryWrapper<OrderOpinionLogDO>()
  2179 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  2180 + .in(OrderOpinionLogDO::getOrderId, orderBaseInfoList);
  2181 + if (!OrderOpinionLogEnum.ORDER_SGS_TEST_FINISH_RESULT.getDesc().equals(orderOpinionLogVO.getOpinionType()) &&
  2182 + !OrderOpinionLogEnum.ORDER_AITEX_TEST_FINISH_RESULT.getDesc().equals(orderOpinionLogVO.getOpinionType())) {
  2183 + //不等于sgs和ailtex
  2184 + orderOpinionWrapper.eq(OrderOpinionLogDO::getOpinionType, orderOpinionLogVO.getOpinionType());
  2185 + } else {
  2186 + orderOpinionWrapper.and(wrapper ->
  2187 + wrapper.eq(OrderOpinionLogDO::getOpinionType, OrderOpinionLogEnum.ORDER_SGS_TEST_FINISH_RESULT.getDesc())
  2188 + .or()
  2189 + .eq(OrderOpinionLogDO::getOpinionType, OrderOpinionLogEnum.ORDER_AITEX_TEST_FINISH_RESULT.getDesc())
  2190 + );
  2191 + }
  2192 + List<OrderOpinionLogDO> orderOpinionLogDOList = orderOpinionLogService.list(orderOpinionWrapper);
  2193 + if (CollectionUtils.isEmpty(orderOpinionLogDOList)) {
  2194 + return ServerResult.fail("订单跟单信息" + orderOpinionLogVO.getOpinionType() + "未填写");
  2195 + }
  2196 + List<Integer> okCountList = new ArrayList();
  2197 + List<Integer> FailCountList = new ArrayList();
  2198 + orderOpinionLogDOList.stream().forEach(x -> {
  2199 + if (x.getField().contains("ok") || x.getField().contains("OK")) {
  2200 + okCountList.add(Constant.ONE);
  2201 + } else if(x.getField().contains("Fail") || x.getField().contains("FAIL") ) {
  2202 + FailCountList.add(Constant.ZERO);
  2203 + }
  2204 + });
  2205 + int sum = okCountList.size() + FailCountList.size();
  2206 + double rate = ((double) okCountList.size() / sum) * Constant.HUNDRED;
  2207 + DecimalFormat decimalFormat = new DecimalFormat("0.00");
  2208 + String resultrate = decimalFormat.format(rate);
  2209 + return ServerResult.success(resultrate + "%");
  2210 + }
  2211 + return ServerResult.fail("返单订单不进行统计!");
  2212 + }
1957 2213  
  2214 + @Override
  2215 + public ServerResult produceReport(ProducePdfVO producePdfVO) {
  2216 + if (CollectionUtils.isEmpty(producePdfVO.getIds()) && org.apache.commons.lang3.StringUtils.isBlank(producePdfVO.getCompanyName())) {
  2217 + return ServerResult.fail("订单id或者公司名称为空");
  2218 + }
  2219 + List<OrderProfitAnalysisDO> orderProfitAnalysisList = profitAnalysisService.list(new LambdaQueryWrapper<OrderProfitAnalysisDO>()
  2220 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  2221 + .in(OrderProfitAnalysisDO::getOrderId, producePdfVO.getIds()));
  2222 + //必须要求每一个订单的利润分析信息都存在,才能生成生产指标书。
  2223 + if (CollectionUtils.isEmpty(orderProfitAnalysisList) || producePdfVO.getIds().size() != orderProfitAnalysisList.size()) {
  2224 + return ServerResult.fail("利润分析未填写,无法进行生成!");
  2225 + }
  2226 + List<OrderFieldLockApplyDO> orderFieldLockApplyDOS = orderFieldLockApplyService.list(new LambdaQueryWrapper<OrderFieldLockApplyDO>()
  2227 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  2228 + .in(OrderFieldLockApplyDO::getOrderId, producePdfVO.getIds())
  2229 + .eq(OrderFieldLockApplyDO::getType, ApplyTypeEnum.ORDER_PROFIT_APPLY.getType())
  2230 + .eq(OrderFieldLockApplyDO::getStatus,ApplyStatusEnum.WAIT_AUDIT.getStatus()));
  2231 + if(CollectionUtils.isNotEmpty(orderFieldLockApplyDOS)){
  2232 + return ServerResult.fail("订单中包含利润未审批的订单,无法生成!");
  2233 + }
  2234 + ProducePdfVO producePdf = pdfUtils.createProducePdf(pdfUtils.build(producePdfVO.getIds()), "生产指示书.pdf", producePdfVO.getCompanyName());
  2235 + return ServerResult.success(producePdf);
  2236 + }
1958 2237  
1959 2238  
1960 2239 /**
... ... @@ -1991,10 +2270,10 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
1991 2270  
1992 2271  
1993 2272 @Override
1994   - public ServerResult checkChargeOrderCount(List<Long> ids) {
  2273 + public ServerResult checkChargeOrderCount(OrderBaseInfoVO baseInfoVO) {
1995 2274 LambdaQueryWrapper<OrderBaseInfoDO> queryWrapper = new LambdaQueryWrapper<OrderBaseInfoDO>()
1996 2275 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
1997   - .in(CollectionUtils.isNotEmpty(ids), OrderBaseInfoDO::getId, ids)
  2276 + .in(CollectionUtils.isNotEmpty(Arrays.asList(baseInfoVO.getId())), OrderBaseInfoDO::getId, Arrays.asList(baseInfoVO.getId()))
1998 2277 .ne(OrderBaseInfoDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
1999 2278 List<OrderBaseInfoDO> ordersDOS = list(queryWrapper);
2000 2279  
... ... @@ -2014,7 +2293,7 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
2014 2293 for (OrderInfoResultVO resultVO : orderInfoResultVOS) {
2015 2294 if (profitAnalysisDOMap.containsKey(resultVO.getId())) {
2016 2295 OrderProfitAnalysisDO profitAnalysisDO = profitAnalysisDOMap.get(resultVO.getId());
2017   - Integer orderCount = resultVO.getOrderCount();
  2296 + Integer orderCount = baseInfoVO.getOrderCount();
2018 2297 BigDecimal customerTotalPrice = new BigDecimal(profitAnalysisDO.getCustomerTotalPrice()).setScale(Constant.TWO, RoundingMode.HALF_UP);
2019 2298 BigDecimal customerPrice = new BigDecimal(profitAnalysisDO.getCustomerPrice()).setScale(Constant.TWO, RoundingMode.HALF_UP);
2020 2299  
... ... @@ -2053,36 +2332,212 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
2053 2332 return orderBaseInfoDOList;
2054 2333 }
2055 2334  
2056   - private void sendOrderInspectionStage(OrderUpdateVO updateVO,String midCheckResult,String endCheckResult){
  2335 + @Override
  2336 + public ServerResult send(ProducePdfVO producePdfVO) throws Exception {
  2337 + if (producePdfVO.getIsSend()) {
  2338 + if (StringUtils.isNotBlank(producePdfVO.getProductionUrl()) && StringUtils.isNotBlank(producePdfVO.getProductionDepartment())) {
  2339 + AdminUserDO produceUser = adminUserService.getOne(new LambdaQueryWrapper<AdminUserDO>()
  2340 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  2341 + .eq(AdminUserDO::getNickName, producePdfVO.getProductionDepartment()));
  2342 + if (Objects.nonNull(produceUser) && org.apache.commons.lang3.StringUtils.isNotBlank(produceUser.getEmail())) {
  2343 + List<String> emails = Arrays.asList(produceUser.getEmail().split("[,,]+"))
  2344 + .stream().map(String::trim)
  2345 + .filter(Objects::nonNull)
  2346 + .collect(Collectors.toList());
  2347 + if(CollectionUtils.isNotEmpty(producePdfVO.getPersonList())){
  2348 + List<AdminUserDO> personUser = adminUserService.list(new LambdaQueryWrapper<AdminUserDO>()
  2349 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  2350 + .in(AdminUserDO::getUserName, producePdfVO.getPersonList()));
  2351 + if(CollectionUtils.isNotEmpty(personUser)){
  2352 + List<String> personList = personUser.stream().map(AdminUserDO::getEmail).filter(Objects::nonNull)
  2353 + .flatMap(email -> Arrays.asList(email.split("[,,]+")).stream())
  2354 + .map(String::trim)
  2355 + .filter(s -> !s.isEmpty())
  2356 + .collect(Collectors.toList());
  2357 + if(CollectionUtils.isNotEmpty(personList)){
  2358 + emails.addAll(personList);
  2359 + }
  2360 + }
  2361 + }
  2362 + URL url1 = new URL(producePdfVO.getProductionUrl());
  2363 + InputStream inputStream = url1.openStream();
  2364 + File file = FileUtil.inputStreamToFile(inputStream, "生产指示书_" + System.currentTimeMillis() + ".pdf");
  2365 + try {
  2366 + emailSendUtils.sendEmail(EmailTemplateEnum.PRODUCE_INDICATE_REPORT, emails, file);
  2367 + } finally {
  2368 + if (file.exists()) {
  2369 + file.delete();
  2370 + System.out.println(file.delete());
  2371 + }
  2372 + }
  2373 + return ServerResult.success("已发送给" + producePdfVO.getProductionDepartment() + "生产科");
  2374 + } else {
  2375 + return ServerResult.fail("生产科邮箱不存在!");
  2376 + }
  2377 + } else {
  2378 + return ServerResult.fail("发送失败!");
  2379 + }
  2380 + }
  2381 + return ServerResult.fail("取消发送!");
  2382 + }
  2383 +
  2384 + private void sendOrderInspectionStage(OrderUpdateVO updateVO, String midCheckResult, String endCheckResult) {
2057 2385 OrderBaseInfoDO orderBaseInfoDO = baseInfoService.getById(updateVO.getOrderId());
2058 2386 AdminUserDO ProductionDepartmentUserDO = userService.getOne(new LambdaQueryWrapper<AdminUserDO>()
2059 2387 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
2060 2388 .eq(AdminUserDO::getUserName, orderBaseInfoDO.getProductionDepartment()));
2061   - if(Objects.nonNull(ProductionDepartmentUserDO)){
  2389 + if (Objects.nonNull(ProductionDepartmentUserDO)) {
2062 2390 OrderEventJobVO orderEventJobVO = new OrderEventJobVO();
2063 2391 orderEventJobVO.setInspectionStageInfo(updateVO.getInspectionStageInfo());
2064 2392 OrderBaseInfoVO orderBaseInfoVo = BeanUtil.copyProperties(orderBaseInfoDO, OrderBaseInfoVO.class);
2065 2393 orderEventJobVO.setBaseInfo(orderBaseInfoVo);
2066   - List<String> emails = Arrays.asList(ProductionDepartmentUserDO.getEmail().split( "[,,]+"))
  2394 + List<String> emails = Arrays.asList(ProductionDepartmentUserDO.getEmail().split("[,,]+"))
2067 2395 .stream().map(String::trim)
  2396 + .filter(Objects::nonNull)
2068 2397 .collect(Collectors.toList());
2069 2398 //一旦修改完质检信息就自动发送邮件对应的生产科。多次编辑保存多次发送。
2070   - if (StringUtils.isNotBlank(updateVO.getInspectionStageInfo().getEndCheckResult()) && !(updateVO.getInspectionStageInfo().getEndCheckResult().equals(endCheckResult))) {
2071   - String EndCheckApplyTime= updateVO.getInspectionStageInfo().getEndCheckApplyTime().substring(0, 10);
2072   - String ProductionDepartmentConsignTime =orderBaseInfoDO.getProductionDepartmentConsignTime().substring(0, 10);
  2399 + if (StringUtils.isNotBlank(updateVO.getInspectionStageInfo().getEndCheckResult()) && !(updateVO.getInspectionStageInfo().getEndCheckResult().equals(endCheckResult))) {
  2400 + String EndCheckApplyTime = "";
  2401 + if (StringUtils.isNotBlank(updateVO.getInspectionStageInfo().getEndCheckApplyTime())) {
  2402 + EndCheckApplyTime = updateVO.getInspectionStageInfo().getEndCheckApplyTime().substring(0, 10);
  2403 + }
  2404 + String ProductionDepartmentConsignTime = orderBaseInfoDO.getProductionDepartmentConsignTime().substring(0, 10);
2073 2405 orderEventJobVO.getInspectionStageInfo().setEndCheckApplyTime(EndCheckApplyTime);
2074 2406 orderEventJobVO.getBaseInfo().setProductionDepartmentConsignTime(ProductionDepartmentConsignTime);
2075   - //尾期验货报告。
2076   - emailSendUtils.sendEmail(EmailTemplateEnum.END_CHECK_REPORT_TEMPLATE, emails, orderEventJobVO);
2077   - }else if(StringUtils.isNotBlank(updateVO.getInspectionStageInfo().getMidCheckResult()) && !(updateVO.getInspectionStageInfo().getMidCheckResult().equals(midCheckResult))){
2078   - String MidCheckApplyTime= updateVO.getInspectionStageInfo().getMidCheckApplyTime().substring(0, 10);
2079   - String ProductionDepartmentConsignTime =orderBaseInfoDO.getProductionDepartmentConsignTime().substring(0, 10);
2080   - String MidCheckApply = DateUtils.format(DateUtils.parseDate(MidCheckApplyTime, DATE), DATE);
2081   - String ProductionDepartmentConsign = DateUtils.format(DateUtils.parseDate(ProductionDepartmentConsignTime,DATE), DATE);
2082   - orderEventJobVO.getInspectionStageInfo().setMidCheckApplyTime(MidCheckApply);
2083   - orderEventJobVO.getBaseInfo().setProductionDepartmentConsignTime(ProductionDepartmentConsign);
2084   - //中期验货报告。
2085   - emailSendUtils.sendEmail(EmailTemplateEnum.MID_CHECK_REPORT_TEMPLATE, emails, orderEventJobVO);
  2407 + LambdaQueryWrapper<ReceiveEmailMappingDO> receiveEmailMappingDOLambdaQueryWrapper = new LambdaQueryWrapper<>();
  2408 + receiveEmailMappingDOLambdaQueryWrapper.eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN);
  2409 + if(!orderBaseInfoDO.getCustomerCode().contains("-") && !orderBaseInfoDO.getCustomerCode().contains("——")){
  2410 + receiveEmailMappingDOLambdaQueryWrapper.eq(ReceiveEmailMappingDO::getTypeValue, orderBaseInfoDO.getCustomerCode())
  2411 + .last("limit 1");
  2412 + }else{
  2413 + receiveEmailMappingDOLambdaQueryWrapper.like(ReceiveEmailMappingDO::getTypeValue,orderBaseInfoDO.getCustomerCode().split("-")[0])
  2414 + .last("limit 1");
  2415 + }
  2416 + ReceiveEmailMappingDO receiveEmailMappingDO = receiveEmailMappingService.getOne( receiveEmailMappingDOLambdaQueryWrapper);
  2417 + //得到所有的质检员。由于删除了角色,但是用户角色表中的信息没有删除,所以不能直接通过用户角色表拿角色,然后发邮件,需校验。
  2418 + List<AdminUserRoleDO> UserRoleList = adminUserRoleService.list(new LambdaQueryWrapper<AdminUserRoleDO>()
  2419 + .eq(AdminUserRoleDO::getRoleId, RoleEnum.INSPECT_USER.getId()));
  2420 + Set<Long> userIdList = UserRoleList.stream().map(AdminUserRoleDO::getUserId).collect(Collectors.toSet());
  2421 + List<AdminUserDO> produceList = adminUserService.list(new LambdaQueryWrapper<AdminUserDO>()
  2422 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  2423 + .in(AdminUserDO::getId, userIdList)
  2424 + .eq(AdminUserDO::getStatus,Constant.ENABLE_TEN));
  2425 + List<String> produceEmailList = produceList.stream().map(AdminUserDO::getEmail).filter(Objects::nonNull)
  2426 + .flatMap(email -> Arrays.asList(email.split("[,,]+")).stream())
  2427 + .map(String::trim)
  2428 + .filter(s -> !s.isEmpty())
  2429 + .collect(Collectors.toList());
  2430 +
  2431 + List<String> emailList = new ArrayList<>();
  2432 + if (Objects.nonNull(receiveEmailMappingDO)) {
  2433 + List<ReceiveEmailConfigItemVO> receiveEmailConfigItemVOList = JSON.parseObject(
  2434 + receiveEmailMappingDO.getConfigInfos(), new TypeReference<List<ReceiveEmailConfigItemVO>>() {
  2435 + });
  2436 + for (ReceiveEmailConfigItemVO item : receiveEmailConfigItemVOList) {
  2437 + if (OrderEventEnum.END_CHECK_REPORT_EVENT.getEvent().equals(item.getEvent())) {
  2438 + emailList = item.getEmails();
  2439 + }
  2440 + }
  2441 + }
  2442 + if (CollectionUtils.isNotEmpty(emails) && CollectionUtils.isNotEmpty(emailList)) {
  2443 + List<String> emailLists = emailList.stream().flatMap(email -> Arrays.stream(email.split("[,,]+"))).collect(Collectors.toList());
  2444 + List<String> combineEmail = new ArrayList<>(emails);
  2445 + if(CollectionUtils.isNotEmpty(produceEmailList)){
  2446 + combineEmail.addAll(produceEmailList);
  2447 + }
  2448 + combineEmail.addAll(emailLists);
  2449 +
  2450 + //尾期验货报告。
  2451 + emailSendUtils.sendEmail(EmailTemplateEnum.END_CHECK_REPORT_TEMPLATE, combineEmail, orderEventJobVO);
  2452 + }
  2453 + } else if (StringUtils.isNotBlank(updateVO.getInspectionStageInfo().getMidCheckResult()) && !(updateVO.getInspectionStageInfo().getMidCheckResult().equals(midCheckResult))) {
  2454 + String MidCheckApplyTime = "";
  2455 + if (StringUtils.isNotBlank(updateVO.getInspectionStageInfo().getMidCheckApplyTime())) {
  2456 + MidCheckApplyTime = updateVO.getInspectionStageInfo().getMidCheckApplyTime().substring(0, 10);
  2457 + }
  2458 + String ProductionDepartmentConsignTime = orderBaseInfoDO.getProductionDepartmentConsignTime().substring(0, 10);
  2459 + orderEventJobVO.getInspectionStageInfo().setMidCheckApplyTime(MidCheckApplyTime);
  2460 + orderEventJobVO.getBaseInfo().setProductionDepartmentConsignTime(ProductionDepartmentConsignTime);
  2461 + LambdaQueryWrapper<ReceiveEmailMappingDO> receiveEmailMappingDOLambdaQueryWrapper = new LambdaQueryWrapper<>();
  2462 + receiveEmailMappingDOLambdaQueryWrapper.eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN);
  2463 + if(!orderBaseInfoDO.getCustomerCode().contains("-") && !orderBaseInfoDO.getCustomerCode().contains("——")){
  2464 + receiveEmailMappingDOLambdaQueryWrapper.eq(ReceiveEmailMappingDO::getTypeValue, orderBaseInfoDO.getCustomerCode())
  2465 + .last("limit 1");
  2466 + }else{
  2467 + receiveEmailMappingDOLambdaQueryWrapper.like(ReceiveEmailMappingDO::getTypeValue,orderBaseInfoDO.getCustomerCode().split("-")[0])
  2468 + .last("limit 1");
  2469 + }
  2470 + ReceiveEmailMappingDO receiveEmailMappingDO = receiveEmailMappingService.getOne( receiveEmailMappingDOLambdaQueryWrapper);
  2471 + //得到所有的质检员。由于删除了角色,但是用户角色表中的信息没有删除,所以不能直接通过用户角色表拿角色,然后发邮件,需校验。
  2472 + List<AdminUserRoleDO> UserRoleList = adminUserRoleService.list(new LambdaQueryWrapper<AdminUserRoleDO>()
  2473 + .eq(AdminUserRoleDO::getRoleId, RoleEnum.INSPECT_USER.getId()));
  2474 + Set<Long> userIdList = UserRoleList.stream().map(AdminUserRoleDO::getUserId).collect(Collectors.toSet());
  2475 + List<AdminUserDO> produceList = adminUserService.list(new LambdaQueryWrapper<AdminUserDO>()
  2476 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  2477 + .in(AdminUserDO::getId, userIdList)
  2478 + .eq(AdminUserDO::getStatus,Constant.ENABLE_TEN));
  2479 + List<String> produceEmailList = produceList.stream().map(AdminUserDO::getEmail).filter(Objects::nonNull)
  2480 + .flatMap(email -> Arrays.asList(email.split("[,,]+")).stream())
  2481 + .map(String::trim)
  2482 + .filter(s -> !s.isEmpty())
  2483 + .collect(Collectors.toList());
  2484 + List<String> emailList = new ArrayList<>();
  2485 + if (Objects.nonNull(receiveEmailMappingDO)) {
  2486 + List<ReceiveEmailConfigItemVO> receiveEmailConfigItemVOList = JSON.parseObject(
  2487 + receiveEmailMappingDO.getConfigInfos(), new TypeReference<List<ReceiveEmailConfigItemVO>>() {
  2488 + });
  2489 + for (ReceiveEmailConfigItemVO item : receiveEmailConfigItemVOList) {
  2490 + if (OrderEventEnum.END_CHECK_REPORT_EVENT.getEvent().equals(item.getEvent())) {
  2491 + emailList = item.getEmails();
  2492 + }
  2493 + }
  2494 + }
  2495 + if (CollectionUtils.isNotEmpty(emails) && CollectionUtils.isNotEmpty(emailList)) {
  2496 + List<String> emailLists = emailList.stream().flatMap(email -> Arrays.stream(email.split("[,,]+"))).collect(Collectors.toList());
  2497 + List<String> combineEmail = new ArrayList<>(emails);
  2498 + if(CollectionUtils.isNotEmpty(produceEmailList)){
  2499 + combineEmail.addAll(produceEmailList);
  2500 + }
  2501 + combineEmail.addAll(emailLists);
  2502 + //中期验货报告。
  2503 + emailSendUtils.sendEmail(EmailTemplateEnum.MID_CHECK_REPORT_TEMPLATE, combineEmail, orderEventJobVO);
  2504 +
  2505 + }
  2506 + }
  2507 + }
  2508 + }
  2509 +
  2510 + private void sendProductionCommentEmail(OrderBaseInfoDO orderBaseInfoDo, String productionComment) {
  2511 + List<AdminUserDO> adminList = adminUserService.list(new LambdaQueryWrapper<AdminUserDO>()
  2512 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  2513 + .in(AdminUserDO::getUserName, Arrays.asList(orderBaseInfoDo.getBusinessPerson(), orderBaseInfoDo.getCreateBy(), orderBaseInfoDo.getProductionDepartment())));
  2514 + if (CollectionUtils.isNotEmpty(adminList)) {
  2515 + List<String> emailsList = adminList.stream().map(AdminUserDO::getEmail).filter(Objects::nonNull).collect(Collectors.toList());
  2516 + if (CollectionUtils.isNotEmpty(emailsList)) {
  2517 + List<String> emailList = emailsList.stream()
  2518 + .flatMap(email -> Arrays.stream(email.split("[,,]+")))
  2519 + .collect(Collectors.toList());
  2520 + if (CollectionUtils.isNotEmpty(emailList)) {
  2521 + OrderEventJobVO orderEventJobVO = new OrderEventJobVO();
  2522 + orderEventJobVO.setBaseInfo(new OrderBaseInfoVO());
  2523 +
  2524 + orderEventJobVO.getBaseInfo().setProjectNo(orderBaseInfoDo.getProjectNo());
  2525 + orderEventJobVO.getBaseInfo().setProductionDepartment(orderBaseInfoDo.getProductionDepartment());
  2526 + orderEventJobVO.getBaseInfo().setInnerNo(orderBaseInfoDo.getInnerNo());
  2527 + orderEventJobVO.getBaseInfo().setCustomerPo(orderBaseInfoDo.getCustomerPo());
  2528 + orderEventJobVO.getBaseInfo().setCustomerStyle(orderBaseInfoDo.getCustomerStyle());
  2529 + orderEventJobVO.getBaseInfo().setPoColor(orderBaseInfoDo.getPoColor());
  2530 + orderEventJobVO.getBaseInfo().setSmallPicUrl(orderBaseInfoDo.getSmallPicUrl());
  2531 + orderEventJobVO.getBaseInfo().setOrderCount(orderBaseInfoDo.getOrderCount());
  2532 +// String[] split = productionComment.split("\n");
  2533 +// String[] split1 = split[split.length - 1].split("[::]+");
  2534 + //这里需要设置不单单只发送最后一条消息。应该是所有的消息。
  2535 +// String lastProductionComment = split1[split1.length - 1];
  2536 + orderEventJobVO.getBaseInfo().setProductionComment(productionComment);
  2537 + orderEventJobVO.getBaseInfo().setProductionDepartmentConsignTime(orderBaseInfoDo.getProductionDepartmentConsignTime().substring(0, 10));
  2538 + //目前是选择的是跟单员邮箱和业务员邮箱。
  2539 + emailSendUtils.sendEmail(EmailTemplateEnum.PRODUCE_IDEA, emailList, orderEventJobVO);
  2540 + }
2086 2541 }
2087 2542 }
2088 2543 }
... ...
src/main/java/com/order/erp/service/order/impl/OrderOpinionLogServiceImpl.java 0 → 100644
  1 +package com.order.erp.service.order.impl;
  2 +
  3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  5 +import com.order.erp.common.constant.Constant;
  6 +import com.order.erp.common.constant.ServerResult;
  7 +import com.order.erp.domain.dto.BaseDO;
  8 +import com.order.erp.domain.dto.order.OrderOpinionLogDO;
  9 +import com.order.erp.domain.vo.order.OrderOpinionLogVO;
  10 +import com.order.erp.mapper.order.OrderOpinionLogMapper;
  11 +import com.order.erp.service.order.OrderOpinionLogService;
  12 +import lombok.extern.slf4j.Slf4j;
  13 +import org.springframework.stereotype.Service;
  14 +
  15 +import java.util.List;
  16 +import java.util.Objects;
  17 +
  18 +
  19 +/**
  20 + * @Author:ch
  21 + * @createTime:2024-08-05
  22 + */
  23 +@Slf4j
  24 +@Service
  25 +public class OrderOpinionLogServiceImpl extends ServiceImpl<OrderOpinionLogMapper, OrderOpinionLogDO> implements OrderOpinionLogService {
  26 + @Override
  27 + public ServerResult queryById(OrderOpinionLogVO orderOpinionLogVo) {
  28 + log.info("orderId"+orderOpinionLogVo.getOrderId());
  29 + System.out.println(orderOpinionLogVo);
  30 + if (Objects.isNull(orderOpinionLogVo.getOrderId())) {
  31 + return ServerResult.fail("OrderId 不能为空");
  32 + }
  33 + List<OrderOpinionLogDO> orderOpinionLogDOList = list(new LambdaQueryWrapper<OrderOpinionLogDO>()
  34 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  35 + .eq(OrderOpinionLogDO::getOrderId, orderOpinionLogVo.getOrderId())
  36 + .orderByDesc(OrderOpinionLogDO::getId));
  37 + return ServerResult.success(orderOpinionLogDOList);
  38 + }
  39 +}
... ...
src/main/resources/images/alterego.png 0 → 100644

441 KB

src/main/resources/images/jqtc.png 0 → 100644

410 KB

src/main/resources/templates/mail.ftl
... ... @@ -43,7 +43,7 @@
43 43 <td> 客户SYSTEM</td>
44 44 <td> PO COLOR</td>
45 45 <td> 订单图片</td>
46   - <td> 生产要求</td>
  46 + <td> 产品意见</td>
47 47 <td> 数量 </td>
48 48 <td> 生产科拖货时间</td>
49 49 <td> 包装类型</td>
... ... @@ -58,7 +58,7 @@
58 58 <td> 客户SYSTEM</td>
59 59 <td> PO COLOR</td>
60 60 <td> 订单图片</td>
61   - <td> 生产要求</td>
  61 + <td> 产品意见</td>
62 62 <td> 数量 </td>
63 63 <td> 生产科拖货时间</td>
64 64 <td> 包装类型</td>
... ... @@ -70,7 +70,7 @@
70 70 <td> 不良2 </td>
71 71 <td> 不良3 </td>
72 72 <td> 包装:卡片、条码、箱贴、箱单 </td>
73   - <td> 期验货结果PASS/FALL </td>
  73 + <td> 期验货结果PASS/FALL </td>
74 74 <#elseif title=="尾期验货日期">
75 75 <td> 客户编码</td>
76 76 <td> 项目号</td>
... ... @@ -80,23 +80,34 @@
80 80 <td> 客户SYSTEM</td>
81 81 <td> PO COLOR</td>
82 82 <td> 订单图片</td>
83   - <td> 生产要求</td>
  83 + <td> 产品意见</td>
84 84 <td> 数量</td>
85 85 <td> 生产科拖货时间</td>
  86 + <#elseif title=="产品意见信息" >
  87 + <td> 项目号</td>
  88 + <td> 生产科</td>
  89 + <td> 内部编号</td>
  90 + <td> 客户PO号</td>
  91 + <td> 客户SYSTEM</td>
  92 + <td> PO COLOR</td>
  93 + <td> 订单图片</td>
  94 + <td> 产品意见</td>
  95 + <td> 数量</td>
  96 + <td> 生产科拖货时间</td>
86 97 <#else>
87   - <td> 客户编码</td>
88   - <td> 项目号</td>
89   - <td> 生产科</td>
90   - <td> 内部编号</td>
91   - <td> 客户PO号</td>
92   - <td> 客户SYSTEM</td>
93   - <td> PO COLOR</td>
94   - <td> 订单图片</td>
95   - <td> 生产要求</td>
96   - <td> 数量</td>
97   - <td> 生产科拖货时间</td>
98   - <td> 订单上的HOD时间</td>
99   - <td> 出库类型</td>
  98 + <td> 客户编码</td>
  99 + <td> 项目号</td>
  100 + <td> 生产科</td>
  101 + <td> 内部编号</td>
  102 + <td> 客户PO号</td>
  103 + <td> 客户SYSTEM</td>
  104 + <td> PO COLOR</td>
  105 + <td> 订单图片</td>
  106 + <td> 产品意见</td>
  107 + <td> 数量</td>
  108 + <td> 生产科拖货时间</td>
  109 + <td> 订单上的HOD时间</td>
  110 + <td> 出库类型</td>
100 111 </#if>
101 112 </tr>
102 113 <tr id="title2">
... ... @@ -148,6 +159,17 @@
148 159 <td>${data.baseInfo.productionComment!" "}</td>
149 160 <td>${data.baseInfo.orderCount! " "}</td>
150 161 <td>${data.baseInfo.productionDepartmentConsignTime! " "}</td>
  162 + <#elseif title=="产品意见信息">
  163 + <td>${data.baseInfo.projectNo! " "}</td>
  164 + <td>${data.baseInfo.productionDepartment! " "}</td>
  165 + <td>${data.baseInfo.innerNo!" "}</td>
  166 + <td>${data.baseInfo.customerPo!" "}</td>
  167 + <td>${data.baseInfo.customerStyle!" "}</td>
  168 + <td>${data.baseInfo.poColor!" "}</td>
  169 + <td><img src="${data.baseInfo.smallPicUrl! " "}" alt="Image"></td>
  170 + <td>${data.baseInfo.productionComment!" "}</td>
  171 + <td>${data.baseInfo.orderCount! " "}</td>
  172 + <td>${data.baseInfo.productionDepartmentConsignTime! " "}</td>
151 173 <#else>
152 174 <td>${data.baseInfo.customerCode! " "}</td>
153 175 <td>${data.baseInfo.projectNo! " "}</td>
... ...