From 2cd9287fdaf7bd15bca8af941344c26b25f4f9b1 Mon Sep 17 00:00:00 2001 From: liuxy Date: Tue, 5 Mar 2024 18:43:21 +0800 Subject: [PATCH] =?UTF-8?q?add=EF=BC=9A=20=E5=90=91=E9=A3=9E=E4=B9=A6?= =?UTF-8?q?=E6=8E=A8=E9=80=81=E5=9B=BE=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/nl/wms/basedata/master/wql/mdcs.xls | Bin 183808 -> 183808 bytes .../java/org/nl/wms/createmsg/CreateMsg.java | 56 ++ .../org/nl/wms/createmsg/DrawFromExcel.java | 852 ++++++++++++++++++ .../main/java/org/nl/wms/createmsg/Grid.java | 70 ++ .../wms/ext/mes/service/LmsToMesService.java | 41 + .../mes/service/impl/LmsToMesServiceImpl.java | 71 ++ .../nl/wms/sch/manage/AutoSendSalesIvt.java | 443 +++++++++ .../main/java/org/nl/wms/sch/wql/AUTO01.wql | 152 ++++ .../main/java/org/nl/wms/sch/wql/TEST0002.wql | 80 ++ 9 files changed, 1765 insertions(+) create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/createmsg/CreateMsg.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/createmsg/DrawFromExcel.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/createmsg/Grid.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AutoSendSalesIvt.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/AUTO01.wql create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/TEST0002.wql diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/master/wql/mdcs.xls b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/master/wql/mdcs.xls index 8e1292637d659d5e84e6e0932d2b00f8a0d52223..20fe0dd0494ff82edd0847751a20aa2b15579f4a 100644 GIT binary patch delta 7475 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 Wh-N|?T+7w(6@w~gIj%oKX#Ee_W^Zu- delta 7349 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 za# grids = null; + List excelRangeAddress = new LinkedList<>();// 单元格合并集合 + + lastRowNum = sheet.getLastRowNum(); + rowSize = sheet.getPhysicalNumberOfRows(); + + for (int i = 0; i < MAX_READ_NUM; i++) { + try { + lastCellNum = sheet.getRow(0).getLastCellNum(); + colSize = sheet.getRow(0).getPhysicalNumberOfCells(); + + break; + } catch (Exception e) { + } + } + + System.out.println("***** " + "获取到excel表格中【最后一行】为:" + lastRowNum + " *****"); + System.out.println("***** " + "获取到excel表格中【最后一列】为:" + lastCellNum + " *****"); + System.out.println("***** " + "获取到excel表格中存在的【物理行数】为:" + rowSize + " *****"); + System.out.println("***** " + "获取到excel表格中存在的【物理列数】为:" + colSize + " *****"); + + rowSize = getRealRowSize(lastRowNum); + colSize = getMaxCellSize(lastRowNum, lastCellNum); + System.out.println("***** " + "处理后excel表格中存在的【最大行数】为:" + rowSize + " *****"); + System.out.println("***** " + "处理后excel表格中存在的【最大列数】为:" + colSize + " *****"); + + if (rowSize == 0) { + throw new Exception("操作异常,未获取到sheet页中的信息,请核查后重试"); + } + + System.out.println(); + + imageWidth = getImageWidth(colSize); + System.out.println("***** " + "计算生成图片的【宽】为:" + imageWidth + " *****"); + + imageHeight = getImageHeight(rowSize); + System.out.println("***** " + "计算生成图片的【高】为:" + imageHeight + " *****"); + + grids = getGrid(rowSize, colSize); + System.out.println("***** " + "获取excel中存在【单元格的数量】为:" + grids.size() + " *****"); + + excelRangeAddress = getMergedRegions(); + System.out.println("***** " + "计算excel中存在【合并单元格的数量】为:" + excelRangeAddress.size() + " *****"); + + countMergeGrid(grids, excelRangeAddress); + System.out.println("***** " + "与单元格合并计算处理后剩余【单元格的数量】为:" + grids.size() + " *****"); + + System.out.println(); + + System.out.println("***** " + "开始绘制图片" + " *****"); + drawImage(imageWidth, imageHeight, grids); + + System.out.println("***** " + "开始生成图片" + " *****"); + ImageIO.write(image, IMAGE_FORMAT, new File(imgPath)); + + } + + /** + * 获取指定的Sheet页,没有指定则获取第一个sheet页 + * + * @param workbook + * @param sheetName + * @return + */ + public static Sheet getSheet(Workbook workbook, String sheetName) { + Sheet sheet = workbook.getSheet(sheetName); + if (null == sheet) { + sheet = workbook.getSheetAt(0); + } + return sheet; + } + + /** + * 获取最大行数 + * + * @param lastRowNum + * @return + */ + public static int getRealRowSize(int lastRowNum) { + Row row = null; + String cellStr = ""; + + while (lastRowNum > 0) { + try { + row = sheet.getRow(lastRowNum); + for (Cell cell : row) { + cellStr = dataFormatter.formatCellValue(cell); + if (null != cellStr && !cellStr.isEmpty()) { + break; + } + } + } catch (Exception e) { + } + + if (null != cellStr && !cellStr.isEmpty()) { + break; + } + lastRowNum--; + } + return lastRowNum + END_ROW_NUM + 1; + } + + /** + * 获取最大的列数,兼容首列为空情况
+ * + * @param lastRowNum + * @param lastCellNum + * @return + */ + public static int getMaxCellSize(int lastRowNum, int lastCellNum) { + int cellSize = 0; + int maxRowNum = 0; + Row row = null; + + while (lastRowNum > 0) { + try { + row = sheet.getRow(lastRowNum); + if (row.getPhysicalNumberOfCells() > cellSize) { + cellSize = row.getPhysicalNumberOfCells(); + maxRowNum = lastRowNum; + } + } catch (Exception e) { + } + lastRowNum--; + } + + return cellSize + countFrontNullColNum(maxRowNum, cellSize) + END_COL_NUM; + } + + /** + * 计算前面空列 当前面的列为空列时,POI获取列最大值会去除空列,按照从A0计算,应该补充前面空列 + * + * @return + */ + public static int countFrontNullColNum(int maxRowNum, int cellSize) { + int nullColNum = 0; + Row row = null; + Cell cell = null; + CellStyle cellStyle = null; + + row = sheet.getRow(maxRowNum); + for (int i = 0; i < cellSize; i++) { + cell = null; + cellStyle = null; + + try { + cell = row.getCell(i); + cellStyle = cell.getCellStyle(); + if (null == cell || null == cellStyle) { + nullColNum++; + } + } catch (Exception e) { + nullColNum++; + } + } + + return nullColNum; + } + + /** + * 获取图片宽度 + * + * @param cellSize + * @return + */ + public static int getImageWidth(int cellSize) { + int imageWidth = 0; + + for (int i = 0; i < cellSize; i++) { + imageWidth += getColumnWidthInPixels(i) + BORDER_WIDTH * 2; + } + return (int) (imageWidth * grid_multiple)+ BORDER_WIDTH * 2; + } + + /** + * 根据excel类型获取单元格宽度 + * + * @param columnIndex + * @return + */ + public static int getColumnWidthInPixels(int columnIndex) { + float result = 0f; + + if (sheet instanceof HSSFSheet) { + int cw = sheet.getColumnWidth(columnIndex); + int def = sheet.getDefaultColumnWidth() * 256; + float px = (cw == def) ? 32.0F : 36.56F; + result = cw / px; + + } else if (sheet instanceof XSSFSheet) { + float widthIn256 = sheet.getColumnWidth(columnIndex); + result = (float) (widthIn256 / 256.0D * 7.001699924468994D); + + } else if (sheet instanceof SXSSFSheet) { + float widthIn256 = sheet.getColumnWidth(columnIndex); + result = (float) (widthIn256 / 256.0D * 7.001699924468994D); + } + return (int) result; + } + + /** + * 获取图片高度 + * + * @param rowSize + * @return + */ + public static int getImageHeight(int rowSize) { + int imageHeight = 0; + Row row = null; + + int nullSum = 0; + + for (int i = 0; i < rowSize; i++) { + row = sheet.getRow(i); + try { + imageHeight += (int) row.getHeightInPoints() + BORDER_WIDTH * 2; + } catch (Exception e) { + imageHeight += DEFAULT_HEIGHT + BORDER_WIDTH * 2; + nullSum++; + } + } + System.out.println("***** " + "计算图片总高度时,发生【空指针】的次数为:" + nullSum + " *****"); + + return (int) (imageHeight * grid_multiple); + } + + /** + * 获取excel的单元格合并的合集 + * + * @return + */ + public static List getMergedRegions() { + List excelRangeAddress = new LinkedList<>(); + int mergedRegionNum = sheet.getNumMergedRegions(); + + for (int i = 0; i < mergedRegionNum; i++) { + excelRangeAddress.add(sheet.getMergedRegion(i)); + } + return excelRangeAddress; + } + + /** + * 获取整体excel的单元格 + * + * @param rowSize + * @param colSiz + * @return + */ + public static List getGrid(int rowSize, int colSiz) { + List grids = new ArrayList<>(); + Grid grid = null; + + Row row = null; + Cell cell = null; + + int rowHeight = 0; + int colWidth = 0; + int x = 0; + int y = 0; + + for (int i = 0; i < rowSize; i++) { + row = sheet.getRow(i); + + /* 如果获取不到高度,则使用默认值 */ + try { + rowHeight = (int) row.getHeightInPoints() + BORDER_WIDTH * 2; + } catch (Exception e) { + rowHeight = DEFAULT_HEIGHT + BORDER_WIDTH * 2; + } + rowHeight = (int) (rowHeight * grid_multiple); + + x = 0; + + /* poi会产生空行获取不到对象的情况,在此主动创建一个对象(行) */ + if (null == row) { + row = sheet.createRow(i); + for (int j = 0; j < colSiz; j++) { + cell = row.createCell(j); + cell.setCellValue(""); + } + } + + /* 遍历excel所有单元格,并赋值给grid,生成集合 */ + for (int j = 0; j < colSiz; j++) { + cell = row.getCell(j); + colWidth = (int) getColumnWidthInPixels(j) + BORDER_WIDTH * 2; + colWidth = (int) (colWidth * grid_multiple); + + grid = new Grid(); + grid.setCell(cell); + grid.setRowNum(i); + grid.setColNum(j); + grid.setX(x); + grid.setY(y); + grid.setHeight(rowHeight); + grid.setWidth(colWidth); + + grids.add(grid); + + x += colWidth; + } + + y += rowHeight; + } + + return grids; + } + + /** + * 计算合并的单元格 + * + * @param grids + * @param excelRangeAddress + */ + @SuppressWarnings("rawtypes") + public static void countMergeGrid(List grids, List excelRangeAddress) { + Map gridMap = new HashMap<>(); + for (Iterator iterator = grids.iterator(); iterator.hasNext();) { + Grid grid = (Grid) iterator.next(); + gridMap.put(grid.getRowNum() + "_" + grid.getColNum(), grid); + } + + int rowNum = 0; + int colNum = 0; + + int firstRow = 0; + int firstColumn = 0; + int lastRow = 0; + int lastColumn = 0; + + Grid endGrid = null; + + for (Iterator iterator = grids.iterator(); iterator.hasNext();) { + Grid grid = (Grid) iterator.next(); + rowNum = grid.getRowNum(); + colNum = grid.getColNum(); + + for (CellRangeAddress cellRange : excelRangeAddress) { + firstRow = cellRange.getFirstRow(); + firstColumn = cellRange.getFirstColumn(); + lastRow = cellRange.getLastRow(); + lastColumn = cellRange.getLastColumn(); + + /* 判断单元格是否在合并单元格区域,存在则重新计算第一个单元格的长宽、其他在合并区域的单元格删除 */ + if (rowNum >= firstRow && rowNum <= lastRow && colNum >= firstColumn && colNum <= lastColumn) { + + if (rowNum == firstRow && colNum == firstColumn) { + endGrid = gridMap.get(lastRow + "_" + lastColumn); + countMergeGridWidth(grid, endGrid); + } else { + iterator.remove(); + } + } + } + } + } + + /** + * 重新计算合并单元格,顶点的宽高 + * + * @param startGrid + * @param endGrid + */ + public static void countMergeGridWidth(Grid startGrid, Grid endGrid) { + int startGridX = startGrid.getX(); + int startGridY = startGrid.getY(); + int endGridX = endGrid.getX(); + int endGridY = endGrid.getY(); + int endGridWidth = endGrid.getWidth(); + int endGridHeight = endGrid.getHeight(); + + startGrid.setWidth(endGridX - startGridX + endGridWidth); + startGrid.setHeight(endGridY - startGridY + endGridHeight); + } + + /** + * 根据grid绘制图片 + * + * @param imageWidth + * @param imageHeight + * @param grids + */ + public static void drawImage(int imageWidth, int imageHeight, List grids) { + image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB); + g2d = image.createGraphics(); + // 平滑字体 + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT); + g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT); + g2d.setRenderingHint(RenderingHints.KEY_TEXT_LCD_CONTRAST, 140); + g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF); + g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_DEFAULT); + g2d.setColor(Color.white); + g2d.fillRect(0, 0, imageWidth, imageHeight); + + fontMetrics = g2d.getFontMetrics(); + + Cell cell = null; + CellStyle cellStyle = null; + BorderStyle borderStyle = null; + + int x = 0; + int y = 0; + int width = 0; + int height = 0; + + for (Grid grid : grids) { + x = grid.getX(); + y = grid.getY(); + width = grid.getWidth(); + height = grid.getHeight(); + + /* 绘制整体表格边框 */ + g2d.setColor(new Color(211, 211, 211)); + g2d.setStroke(new BasicStroke(BORDER_WIDTH)); + g2d.drawRect(x, y, width, height); + } + + org.apache.poi.ss.usermodel.Font poiFont = null; + Font awtFont = null; + + int strWidth = 0; + int strHeight = 0; + + String cellValue = ""; + + for (Grid grid : grids) { + cellValue = ""; + cellStyle = null; + + strWidth = 0; + strHeight = 0; + + cell = grid.getCell(); + cellValue = dataFormatter.formatCellValue(cell); + try { + cellStyle = cell.getCellStyle(); + } catch (Exception e) { + } + x = grid.getX(); + y = grid.getY(); + width = grid.getWidth(); + height = grid.getHeight(); + + /* 绘制存在样式的表格边框 */ + if (null != cellStyle) { + g2d.setColor(Color.black); + g2d.setStroke(new BasicStroke(BORDER_WIDTH)); + + borderStyle = cellStyle.getBorderTop(); + if (borderStyle != BorderStyle.NONE) { + g2d.drawLine(x, y, x + width, y); + } + borderStyle = cellStyle.getBorderBottom(); + if (borderStyle != BorderStyle.NONE) { + g2d.drawLine(x, y + height, x + width, y + height); + } + borderStyle = cellStyle.getBorderLeft(); + if (borderStyle != BorderStyle.NONE) { + g2d.drawLine(x, y, x, y + height); + } + borderStyle = cellStyle.getBorderRight(); + if (borderStyle != BorderStyle.NONE) { + g2d.drawLine(x + width, y, x + width, y + height); + } + } + + /* 绘制单元格背景颜色 */ + g2d.setColor(Color.white); + if (null != cellStyle) { + g2d.setColor(poiColorToAwtColor(cellStyle.getFillForegroundColorColor())); + } + g2d.fillRect(x + BORDER_WIDTH, y + BORDER_WIDTH, width - BORDER_WIDTH, height - BORDER_WIDTH); + + /* 绘制文字 */ + g2d.setColor(Color.black); + + if (cellValue.contains("%")) { + cellValue = cellValue.substring(0, cellValue.indexOf("%")) + " " + "%"; + } + + if (null != cellStyle) { + // 设置字体 + poiFont = workbook.getFontAt(cellStyle.getFontIndexAsInt()); + awtFont = poiFontToAwtFont(poiFont); + g2d.setFont(awtFont); + + // 设置字体颜色 + g2d.setColor(getPoiFontColor(poiFont)); + } + + // 计算字符串宽度和高度 + strWidth = fontMetrics.stringWidth(cellValue); + strHeight = fontMetrics.getHeight(); + + strWidth = (int) (strWidth * font_multiple); + strHeight = (int) (strHeight * ((font_multiple - 1) / 2 + 1)); + + if (width > strWidth) { + x = getDrawStrX(cellStyle, x, width, strWidth); + y = getDrawStrY(cellStyle, y, height, strHeight); + + g2d.drawString(cellValue, x, y); + + } else { + List lines = SplitMultipleRows(cellValue, width, height, strHeight); + + int sumLineHeight = strHeight * lines.size(); + + y = getDrawStrY(cellStyle, y, height, sumLineHeight); + + for (int i = 0; i < lines.size(); i++) { + String str = lines.get(i); + + strWidth = (int) (fontMetrics.stringWidth(str) * font_multiple); + + g2d.drawString(str, getDrawStrX(cellStyle, x, width, strWidth), + y - sumLineHeight / lines.size() * (lines.size() - 1 - i) + BORDER_WIDTH * 2); + } + } + } + g2d.dispose(); + } + + /** + * 根据单元格宽高,及单元格内容,拆分多行 + * + * @param cellValue + * @param width + * @param height + * @param strHeight + * @return + */ + @SuppressWarnings({ "rawtypes", "unused" }) + public static List SplitMultipleRows(String cellValue, int width, int height, int strHeight) { + List lines = new ArrayList<>(); + + if (strHeight > height) { + lines = new ArrayList<>(); + lines.add(cellValue); + + return lines; + } + + char[] valCharArray = cellValue.toCharArray(); + int[] valCharWidthArray = new int[valCharArray.length]; + + StringBuffer strBuffer = new StringBuffer(); + int sumCharWidth = 0; + int sumLineHeight = 0; + + // 分别计算每个字符的宽度 + for (int i = 0; i < valCharArray.length; i++) { + valCharWidthArray[i] = (int) (fontMetrics.stringWidth(String.valueOf(valCharArray[i])) * font_multiple); + } + + // 相加字符,生成多行 + for (int i = 0; i < valCharWidthArray.length; i++) { + + sumCharWidth += valCharWidthArray[i]; + if (sumCharWidth > width) { + lines.add(strBuffer.toString()); + + strBuffer = new StringBuffer(); + sumCharWidth = valCharWidthArray[i]; + } + strBuffer.append(valCharArray[i]); + + if (i == valCharWidthArray.length - 1) { + lines.add(strBuffer.toString()); + } + } + + // 计算多行高度,如果大于表格高度,舍弃下面的行 + for (Iterator iterator = lines.iterator(); iterator.hasNext();) { + String str = (String) iterator.next(); + + sumLineHeight = sumLineHeight + strHeight; + if (sumLineHeight > height) { + sumLineHeight = sumLineHeight - strHeight; + iterator.remove(); + } + } + + return lines; + } + + /** + * 根据cellStyle的对齐方式,获取绘制字符时X的位置 + * + * @param cellStyle + * @param x + * @param width + * @param strWidth + * @return + */ + public static int getDrawStrX(CellStyle cellStyle, int x, int width, int strWidth) { + HorizontalAlignment alignment = null; + try { + alignment = cellStyle.getAlignment(); + + switch (alignment) { + case LEFT: + x = x + BORDER_WIDTH * 2 + FONT_CORRECTED_X; + break; + case CENTER: + x = x + (width - BORDER_WIDTH * 4 - strWidth) / 2 + FONT_CORRECTED_X; + break; + case RIGHT: + x = x + width - BORDER_WIDTH * 2 - strWidth + FONT_CORRECTED_X; + break; + default: + x = x + (width - BORDER_WIDTH * 4 - strWidth) / 2 + FONT_CORRECTED_X; + break; + } + } catch (Exception e) { + x = x + (width - BORDER_WIDTH * 4 - strWidth) / 2 + FONT_CORRECTED_X; + } + + return x; + } + + /** + * 根据cellStyle的对齐方式,获取绘制字符时Y的位置 + * + * @param cellStyle + * @param y + * @param height + * @param strHeight + * @return + */ + public static int getDrawStrY(CellStyle cellStyle, int y, int height, int strHeight) { + VerticalAlignment verticalAlignment = null; + try { + verticalAlignment = cellStyle.getVerticalAlignment(); + + switch (verticalAlignment) { + case TOP: + y = y + BORDER_WIDTH + strHeight - FONT_CORRECTED_Y; + break; + case CENTER: + y = y + BORDER_WIDTH + strHeight + (height - BORDER_WIDTH * 2 - strHeight) / 2 - FONT_CORRECTED_Y; + break; + case BOTTOM: + y = y + height - BORDER_WIDTH - FONT_CORRECTED_Y; + break; + default: + y = y + BORDER_WIDTH + strHeight + (height - BORDER_WIDTH * 2 - strHeight) / 2 - FONT_CORRECTED_Y; + break; + } + } catch (Exception e) { + y = y + BORDER_WIDTH + strHeight + (height - BORDER_WIDTH * 2 - strHeight) / 2 - FONT_CORRECTED_Y; + } + + return y; + } + + /** + * 通过POI字体获取AWT的字体颜色 + * + * @param poiFont + * @return + */ + public static Color getPoiFontColor(org.apache.poi.ss.usermodel.Font poiFont) { + Color awtColor = null; + + if (poiFont instanceof XSSFFont) { + XSSFColor color = ((XSSFFont) poiFont).getXSSFColor(); + String rgbHex = ""; + try { + rgbHex = color.getARGBHex(); + } catch (Exception e) { + HSSFColor color1 = ((HSSFFont) poiFont).getHSSFColor((HSSFWorkbook) workbook); + short[] rgb = color1.getTriplet(); + awtColor = new Color(rgb[255], rgb[0], rgb[0]); + return awtColor; + } + + if (rgbHex != null) { + awtColor = new Color(Integer.parseInt(rgbHex.substring(2), 16)); + } + } else if (poiFont instanceof HSSFFont) { + HSSFColor color = ((HSSFFont) poiFont).getHSSFColor((HSSFWorkbook) workbook); + short[] rgb = color.getTriplet(); + + awtColor = new Color(rgb[0], rgb[1], rgb[2]); + } + + return awtColor; + } + + /** + * POI颜色转AWT颜色 + * + * @param color + * @return + */ + public static Color poiColorToAwtColor(org.apache.poi.ss.usermodel.Color color) { + Color awtColor = null; + + if (color instanceof XSSFColor) { + String rgbHex = ((XSSFColor) color).getARGBHex(); + + if (rgbHex != null) { + awtColor = new Color(Integer.parseInt(rgbHex.substring(2), 16)); + } + } else if (color instanceof HSSFColor) { + short[] s = ((HSSFColor) color).getTriplet(); + + if (s != null) { + awtColor = new Color(s[0], s[1], s[2]); + } + } + return awtColor; + } + + /** + * POI字体转AWT字体 + * + * @param poiFont + * @return + */ + public static Font poiFontToAwtFont(org.apache.poi.ss.usermodel.Font poiFont) { + int poiFontHeight = (int) poiFont.getFontHeightInPoints(); + poiFontHeight = (int) (poiFontHeight * font_multiple); + return new Font(poiFont.getFontName(), Font.PLAIN, poiFontHeight); + } + +} \ No newline at end of file diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/createmsg/Grid.java b/lms/nladmin-system/src/main/java/org/nl/wms/createmsg/Grid.java new file mode 100644 index 000000000..664fd929a --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/createmsg/Grid.java @@ -0,0 +1,70 @@ +package org.nl.wms.createmsg; + +import org.apache.poi.ss.usermodel.Cell; + +public class Grid { + private Cell cell; + private int rowNum; + private int colNum; + private int x; + private int y; + private int width; + private int height; + + public Cell getCell() { + return cell; + } + + public int getRowNum() { + return rowNum; + } + + public int getColNum() { + return colNum; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + public void setCell(Cell cell) { + this.cell = cell; + } + + public void setRowNum(int rowNum) { + this.rowNum = rowNum; + } + + public void setColNum(int colNum) { + this.colNum = colNum; + } + + public void setX(int x) { + this.x = x; + } + + public void setY(int y) { + this.y = y; + } + + public void setWidth(int width) { + this.width = width; + } + + public void setHeight(int height) { + this.height = height; + } + +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/ext/mes/service/LmsToMesService.java b/lms/nladmin-system/src/main/java/org/nl/wms/ext/mes/service/LmsToMesService.java index 0b0104e42..cbc3a2531 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/ext/mes/service/LmsToMesService.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/ext/mes/service/LmsToMesService.java @@ -135,4 +135,45 @@ public interface LmsToMesService { * } */ JSONObject ChildScrapUpdate(JSONObject jo); + + + /** + * 向飞书推送图片 + * @param file_name : 图片名称 + * @return { + * "RTYPE": "S", + * "RTMSG": "图片上传成功", + * "RTOAL": 0, + * "RSYS": null, + * "RTDAT": "img_v3_028m_594c5c05-e1d6-4b2c-8298-445f3df23d4g", + * "RTDAT2": null + * } + */ + JSONObject sendSalesIvtMsg(String file_name); + + /** + * 向飞书推送业务员对应的图片参数 + * @param param { + * "UserList": [ + * { + * "User": "********" //用户工号列表 + * } + * ], + * "Code": "*********", //卡片ID + * "card": { //卡片参数 + * "**": {}, + * "**": {} + * } + * } + * @return { + * "RTYPE": "S", + * "RTMSG": "消息发送成功", + * "RTOAL": 0, + * "RSYS": null, + * "RTDAT": null, + * "RTDAT2": null + * } + */ + JSONObject sendSalesIvtMsgParam(JSONObject param); + } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/ext/mes/service/impl/LmsToMesServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/ext/mes/service/impl/LmsToMesServiceImpl.java index 10fc513b3..520d1bdc0 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/ext/mes/service/impl/LmsToMesServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/ext/mes/service/impl/LmsToMesServiceImpl.java @@ -702,4 +702,75 @@ public class LmsToMesServiceImpl implements LmsToMesService { } return result; } + + @Override + public JSONObject sendSalesIvtMsg(String file_name) { + log.info("sendSalesIvtMsg接口输入参数为:-------------------" + file_name.toString()); + + JSONObject result = new JSONObject(); + if (StrUtil.equals("0", is_connect_mes)) { + result.put("status", HttpStatus.OK.value()); + result.put("message", "下发成功,但未连接飞书!"); + result.put("data", new JSONObject()); + return result; + } + + String url = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode("FEISHU_URL").getValue(); + String api = "/FeiShuNoticesWebApi/UploadImage"; + url = url + api; + + try { + String resultMsg = HttpRequest.get(url) + .body("fileName",file_name) + .execute().body(); + result = JSONObject.parseObject(resultMsg); + log.info("sendSalesIvtMsg接口输出参数为:-------------------" + result.toString()); + + String RTYPE = result.getString("RTYPE"); + if ("E".equals(RTYPE)) { + throw new BadRequestException(result.getString("RTMSG")); + } + + + } catch (Exception e) { + throw new BadRequestException("飞书提示错误:" + e.getMessage()); + } + return result; + } + + @Override + public JSONObject sendSalesIvtMsgParam(JSONObject param) { + log.info("sendSalesIvtMsgParam接口输入参数为:-------------------" + param.toString()); + + JSONObject result = new JSONObject(); + if (StrUtil.equals("0", is_connect_mes)) { + result.put("status", HttpStatus.OK.value()); + result.put("message", "下发成功,但未连接飞书!"); + result.put("data", new JSONObject()); + return result; + } + + String url = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode("FEISHU_URL").getValue(); + String api = "/FeiShuNoticesWebApi/SendCard"; + url = url + api; + + try { + String resultMsg = HttpRequest.post(url) + .body(String.valueOf(param)) + .execute().body(); + result = JSONObject.parseObject(resultMsg); + log.info("sendSalesIvtMsgParam接口输出参数为:-------------------" + result.toString()); + + + String RTYPE = result.getString("RTYPE"); + if ("E".equals(RTYPE)) { + throw new BadRequestException(result.getString("RTMSG")); + } + + + } catch (Exception e) { + throw new BadRequestException("飞书提示错误:" + e.getMessage()); + } + return result; + } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AutoSendSalesIvt.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AutoSendSalesIvt.java new file mode 100644 index 000000000..492a0fb86 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AutoSendSalesIvt.java @@ -0,0 +1,443 @@ +package org.nl.wms.sch.manage; + + +import cn.hutool.core.util.NumberUtil; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.alibaba.excel.write.metadata.fill.FillWrapper; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.nl.common.utils.IdUtil; +import org.nl.modules.common.config.FileProperties; +import org.nl.modules.common.utils.FileUtil; +import org.nl.modules.tools.domain.LocalStorage; +import org.nl.modules.tools.repository.LocalStorageRepository; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.modules.wql.util.SpringContextHolder; +import org.nl.system.service.param.impl.SysParamServiceImpl; +import org.nl.wms.createmsg.CreateMsg; +import org.nl.wms.ext.mes.service.LmsToMesService; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.io.FileOutputStream; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 查询区域对应业务员库存 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class AutoSendSalesIvt { + + private final FileProperties properties; + + private final LocalStorageRepository localStorageRepository; + + private final LmsToMesService lmsToMesService; + + /* + * 填充前路径 + */ + private static String fileName = ""; + + /* + * 填充后路径 + */ + private static String fileNameLast = ""; + + /* + * 模板 + */ + private static String template = ""; + + /* + * 远程地址 + */ + private static String baseApi = "http://60.165.35.2:8011"; + + + public void run() { + fileName = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode("REGION_PERSON_FRIST").getValue(); + fileNameLast = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode("REGION_PERSON_LAST").getValue(); + template = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode("REGION_PERSON_TEMP").getValue(); + // 查询数据 + queryData(); + + } + + /** + * 查询数据 + */ + private void queryData() { + + // 查询所有客户 + List custList = WQL.getWO("TEST0002").addParam("flag", "1") + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + // 查询区域 + List regionList = WQL.getWO("TEST0002").addParam("flag", "2") + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + // 查询区域对应负责人 + List regionPersonList = WQL.getWO("TEST0002").addParam("flag", "3") + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + for (int i = 0; i < regionList.size(); i++) { + String region_code = regionList.get(i).getString("value"); + + // 匹配对应的客户 + List areaCustList = custList.stream() + .filter(row -> row.getString("area").equals(region_code)) + .collect(Collectors.toList()); + + String cust_name_in = areaCustList.stream() + .map(row -> row.getString("cust_name")) + .collect(Collectors.joining("','")); + + // 根据业务员分组 + Map> salesMapList = areaCustList.stream() + .collect(Collectors.groupingBy(row -> row.getString("sales_owner"))); + + // 处理数据 + JSONObject json = regionPersonList.stream() + .filter(row -> row.getString("label").equals(region_code)) + .collect(Collectors.toList()).get(0); + + JSONObject result = dataMang(salesMapList, cust_name_in, json.getString("value")); + result.put("name", regionList.get(i).getString("label")); + result.put("value", regionList.get(i).getString("value")); + + if (result.getJSONArray("data").size() == 1) { + continue; + } + + // 生成excel + createExcel(result); + + } + + } + + /** + * 数据处理 + * @param salesMapList :同一区域所有业务员客户分组 + * @param cust_name_in :客户名称查询条件 + * @param region_head :区域负责人 + */ + private JSONObject dataMang(Map> salesMapList, String cust_name_in ,String region_head) { + + // 查询此区域15天以内所有库存 + List ivtList_15 = WQL.getWO("AUTO01").addParam("flag", "2").addParam("cust_name_in", "('" + cust_name_in + "')") + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + // 查询此区域15-30天以内所有库存 + List ivtList15_30 = WQL.getWO("AUTO01").addParam("flag", "3").addParam("cust_name_in", "('" + cust_name_in + "')") + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + // 查询此区域31-60天以内所有库存 + List ivtList31_60 = WQL.getWO("AUTO01").addParam("flag", "4").addParam("cust_name_in", "('" + cust_name_in + "')") + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + // 查询此区域61-90天以内所有库存 + List ivtList61_90 = WQL.getWO("AUTO01").addParam("flag", "5").addParam("cust_name_in", "('" + cust_name_in + "')") + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + // 查询此区域大于90天所有库存 + List ivtList90 = WQL.getWO("AUTO01").addParam("flag", "6").addParam("cust_name_in", "('" + cust_name_in + "')") + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + // 返回的集合 + List resultListAll = new ArrayList<>(); + // 记录每个业务员对应的数据条数 + List resultSize = new ArrayList<>(); + + double max_day1 = 0.00; + double max_day2 = 0.00; + double max_day3 = 0.00; + double max_day4 = 0.00; + double max_day5 = 0.00; + + for (String sales : salesMapList.keySet()) { + + // 业务员客户集合 + List salesList = salesMapList.get(sales); + + List resultList = new ArrayList<>(); + for (int i = 0; i < salesList.size(); i++) { + JSONObject json = salesList.get(i); + + JSONObject resultJson = new JSONObject(); + resultJson.put("region_head",region_head); + resultJson.put("sales_man",sales); + resultJson.put("cust_name",json.getString("cust_name")); + + // 匹配15以内库存 + double qty15 = ivtList_15.stream() + .filter(row -> row.getString("cust_name").equals(json.getString("cust_name"))) + .map(row -> row.getDoubleValue("canuse_qty")) + .reduce(Double::sum).orElse(0.000); + resultJson.put("day1", NumberUtil.round(qty15, 3)); + + // 匹配15-30以内库存 + double qty15_30 = ivtList15_30.stream() + .filter(row -> row.getString("cust_name").equals(json.getString("cust_name"))) + .map(row -> row.getDoubleValue("canuse_qty")) + .reduce(Double::sum).orElse(0.000); + resultJson.put("day2", NumberUtil.round(qty15_30, 3)); + + // 匹配31-60以内库存 + double qty31_60 = ivtList31_60.stream() + .filter(row -> row.getString("cust_name").equals(json.getString("cust_name"))) + .map(row -> row.getDoubleValue("canuse_qty")) + .reduce(Double::sum).orElse(0.000); + resultJson.put("day3", NumberUtil.round(qty31_60, 3)); + + // 匹配61-90以内库存 + double qty61_90 = ivtList61_90.stream() + .filter(row -> row.getString("cust_name").equals(json.getString("cust_name"))) + .map(row -> row.getDoubleValue("canuse_qty")) + .reduce(Double::sum).orElse(0.000); + resultJson.put("day4", NumberUtil.round(qty61_90, 3)); + + // 匹配大于90的库存 + double qty90 = ivtList90.stream() + .filter(row -> row.getString("cust_name").equals(json.getString("cust_name"))) + .map(row -> row.getDoubleValue("canuse_qty")) + .reduce(Double::sum).orElse(0.000); + resultJson.put("day5", NumberUtil.round(qty90, 3)); + + // 合计 + double day_sum = NumberUtil.add(qty15, qty15_30, qty31_60, qty61_90, qty90).doubleValue(); + resultJson.put("day_sum", NumberUtil.round(day_sum, 3)); + + resultList.add(resultJson); + } + + // 插入小计 + JSONObject jsonMin = new JSONObject(); + jsonMin.put("sales_man", "小计"); + + // 15天以内 + double day1_sum = resultList.stream() + .map(row -> row.getDoubleValue("day1")) + .reduce(Double::sum).orElse(0.00); + jsonMin.put("day1", NumberUtil.round(day1_sum, 3)); + max_day1 = NumberUtil.add(max_day1,day1_sum); + + // 15-30天以内 + double day2_sum = resultList.stream() + .map(row -> row.getDoubleValue("day2")) + .reduce(Double::sum).orElse(0.00); + jsonMin.put("day2", NumberUtil.round(day2_sum, 3)); + max_day2 = NumberUtil.add(max_day2,day2_sum); + + // 31-60天以内 + double day3_sum = resultList.stream() + .map(row -> row.getDoubleValue("day3")) + .reduce(Double::sum).orElse(0.00); + jsonMin.put("day3", NumberUtil.round(day3_sum, 3)); + max_day3 = NumberUtil.add(max_day3,day3_sum); + + // 61-90天以内 + double day4_sum = resultList.stream() + .map(row -> row.getDoubleValue("day4")) + .reduce(Double::sum).orElse(0.00); + jsonMin.put("day4", NumberUtil.round(day4_sum, 3)); + max_day4 = NumberUtil.add(max_day4,day4_sum); + + // 大于90天 + double day5_sum = resultList.stream() + .map(row -> row.getDoubleValue("day5")) + .reduce(Double::sum).orElse(0.00); + jsonMin.put("day5", NumberUtil.round(day5_sum, 3)); + max_day5 = NumberUtil.add(max_day5,day5_sum); + + // 合计 + double day_sum = NumberUtil.add(day1_sum, day2_sum, day3_sum, day4_sum, day5_sum).doubleValue(); + jsonMin.put("day_sum",day_sum); + + resultList.add(jsonMin); + + resultSize.add(resultListAll.size() + resultList.size()+1); + + resultListAll.addAll(resultList); + + } + + // 计算最终合计 + JSONObject jsonSum = new JSONObject(); + jsonSum.put("sales_man", "合计"); + jsonSum.put("day1",NumberUtil.round(max_day1, 3)); + jsonSum.put("day2",NumberUtil.round(max_day2, 3)); + jsonSum.put("day3",NumberUtil.round(max_day3, 3)); + jsonSum.put("day4",NumberUtil.round(max_day4, 3)); + jsonSum.put("day5",NumberUtil.round(max_day5, 3)); + + double day_sum = NumberUtil.add(max_day1, max_day2, max_day3, max_day4, max_day5).doubleValue(); + jsonSum.put("day_sum",day_sum); + + resultListAll.add(jsonSum); + + JSONObject result = new JSONObject(); + result.put("data", resultListAll); + resultSize.add(resultListAll.size()+1); + result.put("size", resultSize); + + return result; + + } + + + /** + * 生成excel + * @param result { + * data:库存数据 + * size:需要填充颜色的第几行 + * } + */ + @SneakyThrows + private void createExcel(JSONObject result) { + + ExcelWriter workBook = EasyExcel.write(fileName).withTemplate(template).build(); + WriteSheet sheet1 = EasyExcel.writerSheet(0).build(); + + // 数据 + List data = result.getJSONArray("data").toJavaList(JSONObject.class); + + // 单组填充 + JSONObject oneJson = new JSONObject(); + oneJson.put("name", result.getString("name")); + workBook.fill(oneJson,sheet1); + // 多组填充 + workBook.fill(new FillWrapper("data", data), sheet1); + workBook.finish(); + + // 添加样式 + // 打开刚生成的excel文件 + Workbook workbook = new XSSFWorkbook(fileName); + + Sheet sheet = workbook.getSheetAt(0); + + List sizeList = result.getJSONArray("size").toJavaList(Integer.class); + + for (int j = 0; j areaList = WQLObject.getWQLObject("md_cs_areasalesinfo") + .query("area = '" + area + "' and is_active = '1'") + .getResultJSONArray(0).toJavaList(JSONObject.class); + + List userList = areaList.stream() + .map(row -> { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("User", row.getString("sales_code")); + return jsonObject; + }) + .collect(Collectors.toList()); + + // 调用接口返回飞书 + JSONObject paramFeiShu = new JSONObject(); + paramFeiShu.put("UserList", userList); + paramFeiShu.put("Code", ""); + paramFeiShu.put("card", resultParam.getString("RTDAT")); + + lmsToMesService.sendSalesIvtMsgParam(paramFeiShu); + } + +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/AUTO01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/AUTO01.wql new file mode 100644 index 000000000..3c740af3a --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/AUTO01.wql @@ -0,0 +1,152 @@ +[交易说明] + 交易名: 业务员区域库存 + 所属模块: + 功能简述: + 版权所有: + 表引用: + 版本经历: + +[数据库] + --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 + +[IO定义] + ################################################# + ## 表字段对应输入参数 + ################################################# + 输入.flag TYPEAS s_string + 输入.cust_name_in TYPEAS f_string + +[临时表] + --这边列出来的临时表就会在运行期动态创建 + +[临时变量] + --所有中间过程变量均可在此处定义 + +[业务过程] + + ########################################## + # 1、输入输出检查 # + ########################################## + + + ########################################## + # 2、主过程前处理 # + ########################################## + + + ########################################## + # 3、业务主过程 # + ########################################## + + IF 输入.flag = "2" + QUERY + SELECT + ivt.canuse_qty / 1000 AS canuse_qty, + cust.cust_code, + cust.cust_name + FROM + st_ivt_structivt ivt + LEFT JOIN st_ivt_structattr attr ON ivt.struct_id = attr.struct_id + LEFT JOIN pdm_bi_subpackagerelation sub ON sub.package_box_sn = attr.storagevehicle_code + AND ivt.pcsn = sub.container_name + INNER JOIN md_cs_customerbase cust ON cust.cust_code = sub.customer_name + WHERE + ivt.canuse_qty > '0' + AND cust.cust_name in 输入.cust_name_in + AND DATEDIFF( NOW(), LEFT(ivt.instorage_time,10) ) < "15" + + ENDSELECT + ENDQUERY + ENDIF + + IF 输入.flag = "3" + QUERY + SELECT + ivt.canuse_qty / 1000 AS canuse_qty, + cust.cust_code, + cust.cust_name + FROM + st_ivt_structivt ivt + LEFT JOIN st_ivt_structattr attr ON ivt.struct_id = attr.struct_id + LEFT JOIN pdm_bi_subpackagerelation sub ON sub.package_box_sn = attr.storagevehicle_code + AND ivt.pcsn = sub.container_name + INNER JOIN md_cs_customerbase cust ON cust.cust_code = sub.customer_name + WHERE + ivt.canuse_qty > '0' + AND cust.cust_name in 输入.cust_name_in + AND ( + DATEDIFF( NOW(), LEFT(ivt.instorage_time,10) ) >= "15" + AND DATEDIFF( NOW(), LEFT(ivt.instorage_time,10) ) <= "30" + ) + ENDSELECT + ENDQUERY + ENDIF + + IF 输入.flag = "4" + QUERY + SELECT + ivt.canuse_qty / 1000 AS canuse_qty, + cust.cust_code, + cust.cust_name + FROM + st_ivt_structivt ivt + LEFT JOIN st_ivt_structattr attr ON ivt.struct_id = attr.struct_id + LEFT JOIN pdm_bi_subpackagerelation sub ON sub.package_box_sn = attr.storagevehicle_code + AND ivt.pcsn = sub.container_name + INNER JOIN md_cs_customerbase cust ON cust.cust_code = sub.customer_name + WHERE + ivt.canuse_qty > '0' + AND cust.cust_name in 输入.cust_name_in + AND ( + DATEDIFF( NOW(), LEFT(ivt.instorage_time,10) ) >= "31" + AND DATEDIFF( NOW(), LEFT(ivt.instorage_time,10) ) <= "60" + ) + + ENDSELECT + ENDQUERY + ENDIF + + IF 输入.flag = "5" + QUERY + SELECT + ivt.canuse_qty / 1000 AS canuse_qty, + cust.cust_code, + cust.cust_name + FROM + st_ivt_structivt ivt + LEFT JOIN st_ivt_structattr attr ON ivt.struct_id = attr.struct_id + LEFT JOIN pdm_bi_subpackagerelation sub ON sub.package_box_sn = attr.storagevehicle_code + AND ivt.pcsn = sub.container_name + INNER JOIN md_cs_customerbase cust ON cust.cust_code = sub.customer_name + WHERE + ivt.canuse_qty > '0' + AND cust.cust_name in 输入.cust_name_in + AND ( + DATEDIFF( NOW(), LEFT(ivt.instorage_time,10) ) >= "61" + AND DATEDIFF( NOW(), LEFT(ivt.instorage_time,10) ) <= "90" + ) + + ENDSELECT + ENDQUERY + ENDIF + + IF 输入.flag = "6" + QUERY + SELECT + ivt.canuse_qty / 1000 AS canuse_qty, + cust.cust_code, + cust.cust_name + FROM + st_ivt_structivt ivt + LEFT JOIN st_ivt_structattr attr ON ivt.struct_id = attr.struct_id + LEFT JOIN pdm_bi_subpackagerelation sub ON sub.package_box_sn = attr.storagevehicle_code + AND ivt.pcsn = sub.container_name + INNER JOIN md_cs_customerbase cust ON cust.cust_code = sub.customer_name + WHERE + ivt.canuse_qty > '0' + AND cust.cust_name in 输入.cust_name_in + AND DATEDIFF( NOW(), LEFT(ivt.instorage_time,10) ) > "90" + + ENDSELECT + ENDQUERY + ENDIF \ No newline at end of file diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/TEST0002.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/TEST0002.wql new file mode 100644 index 000000000..401bcddb0 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/TEST0002.wql @@ -0,0 +1,80 @@ +[交易说明] + 交易名: 成品日报 + 所属模块: + 功能简述: + 版权所有: + 表引用: + 版本经历: + +[数据库] + --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 + +[IO定义] + ################################################# + ## 表字段对应输入参数 + ################################################# + 输入.flag TYPEAS s_string + +[临时表] + --这边列出来的临时表就会在运行期动态创建 + +[临时变量] + --所有中间过程变量均可在此处定义 + +[业务过程] + + ########################################## + # 1、输入输出检查 # + ########################################## + + + ########################################## + # 2、主过程前处理 # + ########################################## + + + ########################################## + # 3、业务主过程 # + ########################################## + + IF 输入.flag = "1" + QUERY + SELECT + cust.*, + info1.area + FROM + md_cs_customerbase cust + INNER JOIN md_cs_areasalesinfo info1 ON info1.sales_name = cust.sales_owner + WHERE + cust.is_delete = '0' + AND cust.is_used = '1' + + ENDSELECT + ENDQUERY + ENDIF + + IF 输入.flag = "2" + QUERY + SELECT + * + FROM + sys_dict + WHERE + code = 'IVT_REIGION' + + ENDSELECT + ENDQUERY + ENDIF + + IF 输入.flag = "3" + QUERY + SELECT + * + FROM + sys_dict + WHERE + code = 'IVT_REIGION_PERSON' + + ENDSELECT + ENDQUERY + ENDIF \ No newline at end of file