|
@@ -1,15 +1,36 @@
|
|
|
package com.jeesite.modules.mes.service;
|
|
package com.jeesite.modules.mes.service;
|
|
|
|
|
|
|
|
import com.jeesite.common.entity.Page;
|
|
import com.jeesite.common.entity.Page;
|
|
|
|
|
+import com.jeesite.common.lang.StringUtils;
|
|
|
import com.jeesite.common.mybatis.mapper.query.QueryType;
|
|
import com.jeesite.common.mybatis.mapper.query.QueryType;
|
|
|
import com.jeesite.common.service.CrudService;
|
|
import com.jeesite.common.service.CrudService;
|
|
|
|
|
+import com.jeesite.common.web.CookieUtils;
|
|
|
import com.jeesite.modules.file.utils.FileUploadUtils;
|
|
import com.jeesite.modules.file.utils.FileUploadUtils;
|
|
|
import com.jeesite.modules.mes.dao.MesScrapDao;
|
|
import com.jeesite.modules.mes.dao.MesScrapDao;
|
|
|
|
|
+import com.jeesite.modules.mes.entity.MesProduct;
|
|
|
import com.jeesite.modules.mes.entity.MesScrap;
|
|
import com.jeesite.modules.mes.entity.MesScrap;
|
|
|
|
|
+import org.apache.poi.ss.usermodel.Cell;
|
|
|
|
|
+import org.apache.poi.ss.usermodel.Row;
|
|
|
|
|
+import org.apache.poi.ss.usermodel.Sheet;
|
|
|
|
|
+import org.apache.poi.ss.usermodel.Workbook;
|
|
|
|
|
+import org.apache.poi.ss.usermodel.WorkbookFactory;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.core.io.ClassPathResource;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
|
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
+import java.io.InputStream;
|
|
|
|
|
+import java.io.OutputStream;
|
|
|
|
|
+import java.net.URLEncoder;
|
|
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
|
+import java.util.HashMap;
|
|
|
|
|
+import java.util.HashSet;
|
|
|
|
|
+import java.util.LinkedHashMap;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+import java.util.Set;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 报废记录Service
|
|
* 报废记录Service
|
|
@@ -18,7 +39,21 @@ import java.util.List;
|
|
|
*/
|
|
*/
|
|
|
@Service
|
|
@Service
|
|
|
public class MesScrapService extends CrudService<MesScrapDao, MesScrap> {
|
|
public class MesScrapService extends CrudService<MesScrapDao, MesScrap> {
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /** 生产报废数据库模板列数 */
|
|
|
|
|
+ private static final int COL_COUNT = 53;
|
|
|
|
|
+ /** 缺陷列(不含报废数/比例/汇总列) */
|
|
|
|
|
+ private static final int[] DEFECT_COLS = {
|
|
|
|
|
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
|
|
|
|
|
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
|
|
|
|
|
+ 41, 42, 43, 44, 45, 46
|
|
|
|
|
+ };
|
|
|
|
|
+ /** 未匹配原因时默认归入精加工-其它 */
|
|
|
|
|
+ private static final int DEFAULT_OTHER_COL = 38;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private MesProductService mesProductService;
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 获取单条数据
|
|
* 获取单条数据
|
|
|
* @param mesScrap
|
|
* @param mesScrap
|
|
@@ -28,7 +63,7 @@ public class MesScrapService extends CrudService<MesScrapDao, MesScrap> {
|
|
|
public MesScrap get(MesScrap mesScrap) {
|
|
public MesScrap get(MesScrap mesScrap) {
|
|
|
return super.get(mesScrap);
|
|
return super.get(mesScrap);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 查询分页数据
|
|
* 查询分页数据
|
|
|
* @param mesScrap 查询条件
|
|
* @param mesScrap 查询条件
|
|
@@ -39,7 +74,7 @@ public class MesScrapService extends CrudService<MesScrapDao, MesScrap> {
|
|
|
public Page<MesScrap> findPage(MesScrap mesScrap) {
|
|
public Page<MesScrap> findPage(MesScrap mesScrap) {
|
|
|
return super.findPage(mesScrap);
|
|
return super.findPage(mesScrap);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 查询列表数据
|
|
* 查询列表数据
|
|
|
* @param mesScrap
|
|
* @param mesScrap
|
|
@@ -49,7 +84,7 @@ public class MesScrapService extends CrudService<MesScrapDao, MesScrap> {
|
|
|
public List<MesScrap> findList(MesScrap mesScrap) {
|
|
public List<MesScrap> findList(MesScrap mesScrap) {
|
|
|
return super.findList(mesScrap);
|
|
return super.findList(mesScrap);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 保存数据(插入或更新)
|
|
* 保存数据(插入或更新)
|
|
|
* @param mesScrap
|
|
* @param mesScrap
|
|
@@ -63,7 +98,7 @@ public class MesScrapService extends CrudService<MesScrapDao, MesScrap> {
|
|
|
// 保存上传附件
|
|
// 保存上传附件
|
|
|
FileUploadUtils.saveFileUpload(mesScrap, mesScrap.getId(), "mesScrap_file");
|
|
FileUploadUtils.saveFileUpload(mesScrap, mesScrap.getId(), "mesScrap_file");
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 更新状态
|
|
* 更新状态
|
|
|
* @param mesScrap
|
|
* @param mesScrap
|
|
@@ -73,7 +108,7 @@ public class MesScrapService extends CrudService<MesScrapDao, MesScrap> {
|
|
|
public void updateStatus(MesScrap mesScrap) {
|
|
public void updateStatus(MesScrap mesScrap) {
|
|
|
super.updateStatus(mesScrap);
|
|
super.updateStatus(mesScrap);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 删除数据
|
|
* 删除数据
|
|
|
* @param mesScrap
|
|
* @param mesScrap
|
|
@@ -94,5 +129,211 @@ public class MesScrapService extends CrudService<MesScrapDao, MesScrap> {
|
|
|
.and("create_date", QueryType.LT, edate);
|
|
.and("create_date", QueryType.LT, edate);
|
|
|
return super.findCount(q);
|
|
return super.findCount(q);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-}
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 按「生产报废数据库」模板导出报废统计
|
|
|
|
|
+ */
|
|
|
|
|
+ public void exportScrapDatabase(List<MesScrap> list, HttpServletResponse response, String fileName) {
|
|
|
|
|
+ try (InputStream in = new ClassPathResource("templates/mes/scrap_export.xls").getInputStream();
|
|
|
|
|
+ Workbook workbook = WorkbookFactory.create(in)) {
|
|
|
|
|
+ Sheet sheet = workbook.getSheetAt(0);
|
|
|
|
|
+ Row headerRow = sheet.getRow(1);
|
|
|
|
|
+ String[] headers = new String[COL_COUNT];
|
|
|
|
|
+ for (int c = 0; c < COL_COUNT; c++) {
|
|
|
|
|
+ headers[c] = getCellString(headerRow, c);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 清除模板示例数据,保留前两行表头
|
|
|
|
|
+ for (int r = sheet.getLastRowNum(); r >= 2; r--) {
|
|
|
|
|
+ Row row = sheet.getRow(r);
|
|
|
|
|
+ if (row != null) {
|
|
|
|
|
+ sheet.removeRow(row);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Map<String, MesProduct> productBySn = loadProducts(list);
|
|
|
|
|
+ Map<String, double[]> rows = new LinkedHashMap<>();
|
|
|
|
|
+
|
|
|
|
|
+ for (MesScrap scrap : list) {
|
|
|
|
|
+ String productName = resolveProductName(scrap, productBySn);
|
|
|
|
|
+ double[] values = rows.computeIfAbsent(productName, k -> new double[COL_COUNT]);
|
|
|
|
|
+ int col = matchDefectColumn(scrap.getReason(), headers);
|
|
|
|
|
+ if (col < 0) {
|
|
|
|
|
+ col = DEFAULT_OTHER_COL;
|
|
|
|
|
+ }
|
|
|
|
|
+ values[col] += 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ int rowIndex = 2;
|
|
|
|
|
+ for (Map.Entry<String, double[]> entry : rows.entrySet()) {
|
|
|
|
|
+ double[] values = entry.getValue();
|
|
|
|
|
+ // 各车间报废数
|
|
|
|
|
+ values[19] = sumRange(values, 9, 18);
|
|
|
|
|
+ values[39] = sumRange(values, 21, 38);
|
|
|
|
|
+ values[47] = sumRange(values, 41, 46);
|
|
|
|
|
+ // 成品报废总数
|
|
|
|
|
+ values[4] = values[19] + values[39] + values[47];
|
|
|
|
|
+ // 毛坯报废总数按压铸合计
|
|
|
|
|
+ values[7] = values[19];
|
|
|
|
|
+ // 料工报废:工=精加工+装配,料=压铸
|
|
|
|
|
+ values[49] = values[39] + values[47];
|
|
|
|
|
+ values[51] = values[19];
|
|
|
|
|
+
|
|
|
|
|
+ Row row = sheet.createRow(rowIndex++);
|
|
|
|
|
+ setCellString(row, 1, entry.getKey());
|
|
|
|
|
+ setCellString(row, 2, "/");
|
|
|
|
|
+ for (int c = 0; c < COL_COUNT; c++) {
|
|
|
|
|
+ if (c == 1 || c == 2) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (c == 0) {
|
|
|
|
|
+ setCellString(row, 0, "");
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ setCellNumber(row, c, values[c]);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ response.reset();
|
|
|
|
|
+ response.setContentType("application/vnd.ms-excel; charset=utf-8");
|
|
|
|
|
+ String encodedName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()).replace("+", "%20");
|
|
|
|
|
+ response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedName);
|
|
|
|
|
+ CookieUtils.setCookie(response, "fileDownload", "true");
|
|
|
|
|
+ try (OutputStream out = response.getOutputStream()) {
|
|
|
|
|
+ workbook.write(out);
|
|
|
|
|
+ out.flush();
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ throw new RuntimeException("导出生产报废数据库失败:" + e.getMessage(), e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private Map<String, MesProduct> loadProducts(List<MesScrap> list) {
|
|
|
|
|
+ Map<String, MesProduct> map = new HashMap<>();
|
|
|
|
|
+ if (list == null || list.isEmpty()) {
|
|
|
|
|
+ return map;
|
|
|
|
|
+ }
|
|
|
|
|
+ Set<String> sns = new HashSet<>();
|
|
|
|
|
+ for (MesScrap scrap : list) {
|
|
|
|
|
+ if (StringUtils.isNotBlank(scrap.getSn())) {
|
|
|
|
|
+ sns.add(scrap.getSn().trim());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (sns.isEmpty()) {
|
|
|
|
|
+ return map;
|
|
|
|
|
+ }
|
|
|
|
|
+ MesProduct query = new MesProduct();
|
|
|
|
|
+ query.getSqlMap().getWhere().and("sn", QueryType.IN, new ArrayList<>(sns));
|
|
|
|
|
+ List<MesProduct> products = mesProductService.findList(query);
|
|
|
|
|
+ if (products != null) {
|
|
|
|
|
+ for (MesProduct product : products) {
|
|
|
|
|
+ if (product != null && StringUtils.isNotBlank(product.getSn())) {
|
|
|
|
|
+ map.put(product.getSn(), product);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return map;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String resolveProductName(MesScrap scrap, Map<String, MesProduct> productBySn) {
|
|
|
|
|
+ if (scrap != null && StringUtils.isNotBlank(scrap.getSn())) {
|
|
|
|
|
+ MesProduct product = productBySn.get(scrap.getSn().trim());
|
|
|
|
|
+ if (product != null && StringUtils.isNotBlank(product.getTitle())) {
|
|
|
|
|
+ return product.getTitle().trim();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (scrap != null && StringUtils.isNotBlank(scrap.getProductCate())) {
|
|
|
|
|
+ return scrap.getProductCate().trim();
|
|
|
|
|
+ }
|
|
|
|
|
+ if (scrap != null && StringUtils.isNotBlank(scrap.getSn())) {
|
|
|
|
|
+ return scrap.getSn().trim();
|
|
|
|
|
+ }
|
|
|
|
|
+ return "未知产品";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 按报废原因匹配模板缺陷列:精确匹配优先,其次包含匹配;同名列按精加工 > 压铸 > 装配顺序。
|
|
|
|
|
+ */
|
|
|
|
|
+ private int matchDefectColumn(String reason, String[] headers) {
|
|
|
|
|
+ if (StringUtils.isBlank(reason)) {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ String target = reason.trim();
|
|
|
|
|
+ List<Integer> exact = new ArrayList<>();
|
|
|
|
|
+ List<Integer> contains = new ArrayList<>();
|
|
|
|
|
+ for (int col : DEFECT_COLS) {
|
|
|
|
|
+ String header = headers[col];
|
|
|
|
|
+ if (StringUtils.isBlank(header)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (header.equals(target)) {
|
|
|
|
|
+ exact.add(col);
|
|
|
|
|
+ } else if (header.contains(target) || target.contains(header)) {
|
|
|
|
|
+ contains.add(col);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!exact.isEmpty()) {
|
|
|
|
|
+ return preferColumn(exact);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!contains.isEmpty()) {
|
|
|
|
|
+ return preferColumn(contains);
|
|
|
|
|
+ }
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private int preferColumn(List<Integer> cols) {
|
|
|
|
|
+ Integer best = null;
|
|
|
|
|
+ int bestScore = -1;
|
|
|
|
|
+ for (Integer col : cols) {
|
|
|
|
|
+ int score;
|
|
|
|
|
+ if (col >= 21 && col <= 38) {
|
|
|
|
|
+ score = 3; // 精加工
|
|
|
|
|
+ } else if (col >= 9 && col <= 18) {
|
|
|
|
|
+ score = 2; // 压铸
|
|
|
|
|
+ } else {
|
|
|
|
|
+ score = 1; // 装配
|
|
|
|
|
+ }
|
|
|
|
|
+ if (score > bestScore) {
|
|
|
|
|
+ bestScore = score;
|
|
|
|
|
+ best = col;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return best == null ? cols.get(0) : best;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private double sumRange(double[] values, int from, int to) {
|
|
|
|
|
+ double sum = 0;
|
|
|
|
|
+ for (int i = from; i <= to; i++) {
|
|
|
|
|
+ sum += values[i];
|
|
|
|
|
+ }
|
|
|
|
|
+ return sum;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String getCellString(Row row, int col) {
|
|
|
|
|
+ if (row == null) {
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+ Cell cell = row.getCell(col);
|
|
|
|
|
+ if (cell == null) {
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+ return StringUtils.trimToEmpty(cell.toString());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void setCellString(Row row, int col, String value) {
|
|
|
|
|
+ Cell cell = row.getCell(col);
|
|
|
|
|
+ if (cell == null) {
|
|
|
|
|
+ cell = row.createCell(col);
|
|
|
|
|
+ }
|
|
|
|
|
+ cell.setCellValue(value == null ? "" : value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void setCellNumber(Row row, int col, double value) {
|
|
|
|
|
+ Cell cell = row.getCell(col);
|
|
|
|
|
+ if (cell == null) {
|
|
|
|
|
+ cell = row.createCell(col);
|
|
|
|
|
+ }
|
|
|
|
|
+ cell.setCellValue(value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|