|
|
@@ -0,0 +1,298 @@
|
|
|
+package com.jeesite.modules.mes.service;
|
|
|
+
|
|
|
+import cn.hutool.extra.qrcode.QrCodeUtil;
|
|
|
+import com.jeesite.common.codec.DesUtils;
|
|
|
+import com.jeesite.common.collect.ListUtils;
|
|
|
+import com.jeesite.common.config.Global;
|
|
|
+import com.jeesite.common.lang.DateUtils;
|
|
|
+import com.jeesite.common.lang.StringUtils;
|
|
|
+import com.jeesite.common.utils.excel.ExcelExport;
|
|
|
+import com.jeesite.modules.mes.entity.MesLineProcessUser;
|
|
|
+import com.jeesite.modules.mes.entity.MesUserAuthExport;
|
|
|
+import com.jeesite.modules.sys.dao.UserRoleDao;
|
|
|
+import com.jeesite.modules.sys.entity.EmpUser;
|
|
|
+import com.jeesite.modules.sys.entity.Role;
|
|
|
+import com.jeesite.modules.sys.entity.User;
|
|
|
+import com.jeesite.modules.sys.entity.UserRole;
|
|
|
+import com.jeesite.modules.sys.service.EmpUserService;
|
|
|
+import com.jeesite.modules.sys.service.RoleService;
|
|
|
+import com.jeesite.modules.sys.service.UserService;
|
|
|
+import org.apache.poi.ss.usermodel.Cell;
|
|
|
+import org.apache.poi.ss.usermodel.CellStyle;
|
|
|
+import org.apache.poi.ss.usermodel.CellType;
|
|
|
+import org.apache.poi.ss.usermodel.ClientAnchor;
|
|
|
+import org.apache.poi.ss.usermodel.Drawing;
|
|
|
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
|
|
|
+import org.apache.poi.ss.usermodel.Row;
|
|
|
+import org.apache.poi.ss.usermodel.Sheet;
|
|
|
+import org.apache.poi.ss.usermodel.VerticalAlignment;
|
|
|
+import org.apache.poi.ss.usermodel.Workbook;
|
|
|
+import org.apache.poi.util.Units;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.LinkedHashSet;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 员工权限导出 Service
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class MesEmpUserExportService {
|
|
|
+
|
|
|
+ private static final int QRCODE_COLUMN_INDEX = 2;
|
|
|
+ private static final int QRCODE_SIZE = 200;
|
|
|
+ private static final int QRCODE_DISPLAY_SIZE_PX = 120;
|
|
|
+ private static final float QRCODE_ROW_HEIGHT = 95F;
|
|
|
+ private static final float MIN_ROW_HEIGHT = 15F;
|
|
|
+ private static final float LINE_HEIGHT = 15F;
|
|
|
+ /** ExcelExport 会先写标题行和表头行,数据从第 3 行开始 */
|
|
|
+ private static final int DATA_ROW_OFFSET = 2;
|
|
|
+ private static final int[] COLUMN_WIDTH_CHARS = {14, 18, 22, 50};
|
|
|
+ private static final String MULTI_VALUE_SEPARATOR = "、";
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private EmpUserService empUserService;
|
|
|
+ @Autowired
|
|
|
+ private UserService userService;
|
|
|
+ @Autowired
|
|
|
+ private RoleService roleService;
|
|
|
+ @Autowired
|
|
|
+ private UserRoleDao userRoleDao;
|
|
|
+ @Autowired
|
|
|
+ private MesLineProcessUserService mesLineProcessUserService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 组装员工权限导出数据(一行一个用户)
|
|
|
+ */
|
|
|
+ public List<MesUserAuthExport> findUserAuthExportList() {
|
|
|
+ List<EmpUser> userList = empUserService.findList(new EmpUser());
|
|
|
+ if (ListUtils.isEmpty(userList)) {
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, String> loginCodeMap = buildLoginCodeMap(userList);
|
|
|
+ Map<String, String> roleNameMap = buildRoleNameMap();
|
|
|
+ Map<String, List<String>> userRoleMap = buildUserRoleMap(roleNameMap);
|
|
|
+ Map<String, List<MesLineProcessUser>> userOprnoMap = buildUserOprnoMap();
|
|
|
+ String secretKey = Global.getConfig("shiro.loginSubmit.secretKey");
|
|
|
+
|
|
|
+ List<MesUserAuthExport> result = new ArrayList<>();
|
|
|
+ for (EmpUser user : userList) {
|
|
|
+ if (user == null || StringUtils.isBlank(user.getUserCode())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ MesUserAuthExport row = new MesUserAuthExport();
|
|
|
+ row.setUserName(user.getUserName());
|
|
|
+ row.setRoleNames(joinList(userRoleMap.get(user.getUserCode())));
|
|
|
+ row.setOprnoAuth(defaultDisplay(formatOprnos(userOprnoMap.get(user.getUserCode()))));
|
|
|
+ String loginCode = loginCodeMap.get(user.getUserCode());
|
|
|
+ if (StringUtils.isNotBlank(loginCode)) {
|
|
|
+ row.setQrcode(DesUtils.encode(loginCode, secretKey));
|
|
|
+ }
|
|
|
+ result.add(row);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 导出员工权限 Excel(二维码列嵌入图片)
|
|
|
+ */
|
|
|
+ public void exportUserAuth(HttpServletResponse response) {
|
|
|
+ List<MesUserAuthExport> list = findUserAuthExportList();
|
|
|
+ List<String> qrcodeContents = new ArrayList<>(list.size());
|
|
|
+ for (MesUserAuthExport row : list) {
|
|
|
+ qrcodeContents.add(row.getQrcode());
|
|
|
+ row.setQrcode("");
|
|
|
+ }
|
|
|
+ String fileName = "员工权限导出" + DateUtils.getDate("yyyyMMddHHmmss") + ".xlsx";
|
|
|
+ try (ExcelExport ee = new ExcelExport("员工权限导出", MesUserAuthExport.class)) {
|
|
|
+ ee.setDataList(list);
|
|
|
+ finalizeExportSheet(ee.getWorkbook(), list.size(), qrcodeContents);
|
|
|
+ ee.write(response, fileName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void finalizeExportSheet(Workbook workbook, int dataSize, List<String> qrcodeContents) {
|
|
|
+ if (workbook == null || dataSize <= 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Sheet sheet = workbook.getNumberOfSheets() > 0 ? workbook.getSheetAt(0) : null;
|
|
|
+ if (sheet == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for (int i = 0; i < COLUMN_WIDTH_CHARS.length; i++) {
|
|
|
+ sheet.setColumnWidth(i, COLUMN_WIDTH_CHARS[i] * 256);
|
|
|
+ }
|
|
|
+ Drawing<?> drawing = sheet.createDrawingPatriarch();
|
|
|
+ for (int i = 0; i < dataSize; i++) {
|
|
|
+ int rowIndex = i + DATA_ROW_OFFSET;
|
|
|
+ Row row = sheet.getRow(rowIndex);
|
|
|
+ if (row == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ float textHeight = MIN_ROW_HEIGHT;
|
|
|
+ for (int col = 0; col < COLUMN_WIDTH_CHARS.length; col++) {
|
|
|
+ if (col == QRCODE_COLUMN_INDEX) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Cell cell = row.getCell(col);
|
|
|
+ if (cell == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ applyWrapStyle(workbook, cell);
|
|
|
+ textHeight = Math.max(textHeight, calculateWrapHeight(getCellStringValue(cell), COLUMN_WIDTH_CHARS[col]));
|
|
|
+ }
|
|
|
+ boolean hasQrcode = i < qrcodeContents.size() && StringUtils.isNotBlank(qrcodeContents.get(i));
|
|
|
+ float rowHeight = Math.max(textHeight, hasQrcode ? QRCODE_ROW_HEIGHT : MIN_ROW_HEIGHT);
|
|
|
+ row.setHeightInPoints(rowHeight);
|
|
|
+ if (hasQrcode) {
|
|
|
+ appendQrcodeImage(workbook, drawing, row, rowIndex, qrcodeContents.get(i));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void applyWrapStyle(Workbook workbook, Cell cell) {
|
|
|
+ CellStyle style = workbook.createCellStyle();
|
|
|
+ CellStyle existing = cell.getCellStyle();
|
|
|
+ if (existing != null) {
|
|
|
+ style.cloneStyleFrom(existing);
|
|
|
+ }
|
|
|
+ style.setWrapText(true);
|
|
|
+ style.setVerticalAlignment(VerticalAlignment.CENTER);
|
|
|
+ style.setAlignment(HorizontalAlignment.CENTER);
|
|
|
+ cell.setCellStyle(style);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void appendQrcodeImage(Workbook workbook, Drawing<?> drawing, Row row, int rowIndex, String content) {
|
|
|
+ Cell cell = row.getCell(QRCODE_COLUMN_INDEX);
|
|
|
+ if (cell == null) {
|
|
|
+ cell = row.createCell(QRCODE_COLUMN_INDEX);
|
|
|
+ }
|
|
|
+ cell.setCellValue("");
|
|
|
+ byte[] pngBytes = QrCodeUtil.generatePng(content, QRCODE_SIZE, QRCODE_SIZE);
|
|
|
+ int pictureIndex = workbook.addPicture(pngBytes, Workbook.PICTURE_TYPE_PNG);
|
|
|
+ int margin = Units.pixelToEMU(4);
|
|
|
+ int size = Units.pixelToEMU(QRCODE_DISPLAY_SIZE_PX);
|
|
|
+ ClientAnchor anchor = drawing.createAnchor(margin, margin, margin + size, margin + size,
|
|
|
+ QRCODE_COLUMN_INDEX, rowIndex, QRCODE_COLUMN_INDEX, rowIndex);
|
|
|
+ drawing.createPicture(anchor, pictureIndex);
|
|
|
+ }
|
|
|
+
|
|
|
+ private float calculateWrapHeight(String text, int columnWidthChars) {
|
|
|
+ if (StringUtils.isBlank(text)) {
|
|
|
+ return MIN_ROW_HEIGHT;
|
|
|
+ }
|
|
|
+ int maxLineLength = Math.max(columnWidthChars, 1);
|
|
|
+ String[] lines = text.split("\\R");
|
|
|
+ int totalLines = 0;
|
|
|
+ for (String line : lines) {
|
|
|
+ totalLines += Math.max(1, (int) Math.ceil((double) line.length() / maxLineLength));
|
|
|
+ }
|
|
|
+ return Math.min(totalLines * LINE_HEIGHT + 5F, 409F);
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getCellStringValue(Cell cell) {
|
|
|
+ if (cell == null) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ if (cell.getCellType() == CellType.STRING) {
|
|
|
+ return cell.getStringCellValue();
|
|
|
+ }
|
|
|
+ if (cell.getCellType() == CellType.NUMERIC) {
|
|
|
+ return String.valueOf(cell.getNumericCellValue());
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, String> buildLoginCodeMap(List<EmpUser> userList) {
|
|
|
+ Map<String, String> loginCodeMap = new HashMap<>();
|
|
|
+ for (EmpUser user : userList) {
|
|
|
+ if (user == null || StringUtils.isBlank(user.getUserCode())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(user.getLoginCode())) {
|
|
|
+ loginCodeMap.put(user.getUserCode(), user.getLoginCode());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ User fullUser = userService.get(user.getUserCode());
|
|
|
+ if (fullUser != null && StringUtils.isNotBlank(fullUser.getLoginCode())) {
|
|
|
+ loginCodeMap.put(user.getUserCode(), fullUser.getLoginCode());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return loginCodeMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, String> buildRoleNameMap() {
|
|
|
+ Map<String, String> roleNameMap = new HashMap<>();
|
|
|
+ List<Role> roleList = roleService.findList(new Role());
|
|
|
+ if (ListUtils.isEmpty(roleList)) {
|
|
|
+ return roleNameMap;
|
|
|
+ }
|
|
|
+ for (Role role : roleList) {
|
|
|
+ if (role != null && StringUtils.isNotBlank(role.getRoleCode())) {
|
|
|
+ roleNameMap.put(role.getRoleCode(), StringUtils.defaultString(role.getRoleName(), role.getRoleCode()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return roleNameMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, List<String>> buildUserRoleMap(Map<String, String> roleNameMap) {
|
|
|
+ Map<String, List<String>> userRoleMap = new HashMap<>();
|
|
|
+ List<UserRole> userRoleList = userRoleDao.findList(new UserRole());
|
|
|
+ if (ListUtils.isEmpty(userRoleList)) {
|
|
|
+ return userRoleMap;
|
|
|
+ }
|
|
|
+ for (UserRole userRole : userRoleList) {
|
|
|
+ if (userRole == null || StringUtils.isBlank(userRole.getUserCode())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String roleName = roleNameMap.getOrDefault(userRole.getRoleCode(), userRole.getRoleCode());
|
|
|
+ userRoleMap.computeIfAbsent(userRole.getUserCode(), k -> new ArrayList<>()).add(roleName);
|
|
|
+ }
|
|
|
+ return userRoleMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, List<MesLineProcessUser>> buildUserOprnoMap() {
|
|
|
+ return mesLineProcessUserService.findList(new MesLineProcessUser()).stream()
|
|
|
+ .filter(item -> item != null && StringUtils.isNotBlank(item.getUserCode()))
|
|
|
+ .collect(Collectors.groupingBy(MesLineProcessUser::getUserCode));
|
|
|
+ }
|
|
|
+
|
|
|
+ private String formatOprnos(List<MesLineProcessUser> processUsers) {
|
|
|
+ if (ListUtils.isEmpty(processUsers)) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ Set<String> items = new LinkedHashSet<>();
|
|
|
+ for (MesLineProcessUser processUser : processUsers) {
|
|
|
+ if (processUser != null && StringUtils.isNotBlank(processUser.getOprno())) {
|
|
|
+ items.add(processUser.getOprno());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return joinSet(items);
|
|
|
+ }
|
|
|
+
|
|
|
+ private String joinList(List<String> list) {
|
|
|
+ if (ListUtils.isEmpty(list)) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ return String.join(MULTI_VALUE_SEPARATOR, list);
|
|
|
+ }
|
|
|
+
|
|
|
+ private String joinSet(Set<String> set) {
|
|
|
+ if (set == null || set.isEmpty()) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ return String.join(MULTI_VALUE_SEPARATOR, set);
|
|
|
+ }
|
|
|
+
|
|
|
+ private String defaultDisplay(String value) {
|
|
|
+ return StringUtils.isBlank(value) ? "无" : value;
|
|
|
+ }
|
|
|
+}
|