新增打印业务绑定功能,整合原材料卡片和入场记录的打印模板配置,优化打印数据准备逻辑。新增打印机查询接口,提升打印服务的灵活性和用户体验。同时,重构相关控制器以支持新的打印常量定义,增强系统的可维护性和扩展性。

This commit is contained in:
geht
2026-05-13 17:25:13 +08:00
parent c3f8190537
commit 642cecb04d
29 changed files with 2265 additions and 217 deletions

View File

@@ -0,0 +1,15 @@
package org.jeecg.modules.xslmes.constant;
/**
* 打印业务绑定 biz_code 使用菜单 permission id与 print_biz_perm_entity、Flyway 中原材料卡片菜单一致。
*/
public final class MesXslPrintConstants {
/** 原材料卡片页面菜单sys_permission.id */
public static final String RAW_MATERIAL_CARD_PERM_ID = "1900000000000000540";
/** 原料入场记录页面菜单sys_permission.id与 Flyway 中 parent 菜单一致) */
public static final String RAW_MATERIAL_ENTRY_PERM_ID = "1900000000000000530";
private MesXslPrintConstants() {}
}

View File

@@ -22,6 +22,7 @@ import org.jeecg.modules.print.service.IPrintBizTemplateBindService;
import org.jeecg.modules.print.service.IPrintTemplateService;
import org.jeecg.modules.print.util.PrintBizDataMappingUtil;
import org.jeecg.modules.xslmes.constant.MesXslCustomerBizStatus;
import org.jeecg.modules.xslmes.constant.MesXslPrintConstants;
import org.jeecg.modules.xslmes.entity.MesXslCustomer;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialCard;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialEntry;
@@ -620,8 +621,6 @@ public class MesXslDesktopAnonController {
return Result.OK((int) count);
}
/** 与 PrintBizTypeCatalog / 业务打印绑定一致 */
private static final String RAW_MATERIAL_CARD_BIZ_CODE = "MES_RAW_MATERIAL_CARD";
@Operation(summary = "原材料卡片-免密准备原生打印数据(桌面端用)")
@GetMapping("/xslmes/mesXslRawMaterialCard/anon/prepareNativePrint")
@@ -629,7 +628,8 @@ public class MesXslDesktopAnonController {
try {
MesXslRawMaterialCard card = rawMaterialCardService.getById(id);
if (card == null) return Result.error("未找到原材料卡片");
PrintBizTemplateBind bind = printBizTemplateBindService.getByBizCode(RAW_MATERIAL_CARD_BIZ_CODE);
PrintBizTemplateBind bind =
printBizTemplateBindService.getByBizCode(MesXslPrintConstants.RAW_MATERIAL_CARD_PERM_ID);
if (bind == null) return Result.error("请先在「业务打印绑定」中配置原材料卡片与打印模板");
PrintTemplate tpl = printTemplateService.getById(bind.getTemplateId());
if (tpl == null) return Result.error("绑定的打印模板不存在");
@@ -648,6 +648,32 @@ public class MesXslDesktopAnonController {
}
}
@Operation(summary = "原料入场记录-免密准备原生打印数据(桌面端用)")
@GetMapping("/xslmes/mesXslRawMaterialEntry/anon/prepareNativePrint")
public Result<Map<String, Object>> rawMaterialEntryAnonPrepareNativePrint(@RequestParam(name = "id") String id) {
try {
MesXslRawMaterialEntry entry = rawMaterialEntryService.getById(id);
if (entry == null) return Result.error("未找到原料入场记录");
PrintBizTemplateBind bind =
printBizTemplateBindService.getByBizCode(MesXslPrintConstants.RAW_MATERIAL_ENTRY_PERM_ID);
if (bind == null) return Result.error("请先在「业务打印绑定」中配置原料入场记录与打印模板");
PrintTemplate tpl = printTemplateService.getById(bind.getTemplateId());
if (tpl == null) return Result.error("绑定的打印模板不存在");
ArrayNode mapping = PrintBizDataMappingUtil.parseMappingArray(bind.getFieldMappingJson());
JsonNode bizRoot = objectMapper.valueToTree(entry);
ObjectNode printData = PrintBizDataMappingUtil.mapBizToPrintData(bizRoot, mapping);
Map<String, Object> out = new HashMap<>(8);
out.put("entryId", entry.getId());
out.put("templateCode", bind.getTemplateCode());
out.put("templateJson", tpl.getTemplateJson());
out.put("printData", objectMapper.convertValue(printData, Map.class));
return Result.OK(out);
} catch (Exception e) {
log.error("原料入场记录-免密准备打印数据失败 id={}", id, e);
return Result.error("准备打印数据失败: " + e.getMessage());
}
}
// ═══════════════════════════ 仓库管理(只读,供桌面端下拉选取) ═══════════════════════════
@Operation(summary = "仓库-免密分页列表查询(供桌面端筛选使用)")

View File

@@ -29,6 +29,7 @@ import org.jeecg.modules.print.service.IPrintTemplateService;
import org.jeecg.modules.print.support.PrintServerEnvironmentService;
import org.jeecg.modules.print.support.PrintServerPdfJobService;
import org.jeecg.modules.print.util.PrintBizDataMappingUtil;
import org.jeecg.modules.xslmes.constant.MesXslPrintConstants;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialCard;
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialCardService;
import org.jeecg.modules.xslmes.service.MesXslStompNotifyService;
@@ -56,9 +57,6 @@ import org.springframework.web.servlet.ModelAndView;
@Slf4j
public class MesXslRawMaterialCardController extends JeecgController<MesXslRawMaterialCard, IMesXslRawMaterialCardService> {
/** 与 PrintBizTypeCatalog / 业务打印绑定一致 */
private static final String RAW_MATERIAL_CARD_BIZ_CODE = "MES_RAW_MATERIAL_CARD";
@Autowired
private IMesXslRawMaterialCardService mesXslRawMaterialCardService;
@Autowired
@@ -184,7 +182,7 @@ public class MesXslRawMaterialCardController extends JeecgController<MesXslRawMa
return Result.error("未找到原材料卡片");
}
PrintBizTemplateBind bind =
printBizTemplateBindService.getByBizCode(RAW_MATERIAL_CARD_BIZ_CODE);
printBizTemplateBindService.getByBizCode(MesXslPrintConstants.RAW_MATERIAL_CARD_PERM_ID);
if (bind == null) {
return Result.error("请先在「业务打印绑定」中配置原材料卡片与打印模板");
}

View File

@@ -1,28 +1,50 @@
package org.jeecg.modules.xslmes.controller;
import java.util.Arrays;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialEntry;
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialEntryService;
import org.jeecg.modules.xslmes.service.MesXslStompNotifyService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import io.swagger.v3.oas.annotations.tags.Tag;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.swagger.v3.oas.annotations.Operation;
import org.jeecg.common.aspect.annotation.AutoLog;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.print.entity.PrintBizTemplateBind;
import org.jeecg.modules.print.entity.PrintTemplate;
import org.jeecg.modules.print.service.IPrintBizTemplateBindService;
import org.jeecg.modules.print.service.IPrintTemplateService;
import org.jeecg.modules.print.support.PrintServerEnvironmentService;
import org.jeecg.modules.print.support.PrintServerPdfJobService;
import org.jeecg.modules.print.util.PrintBizDataMappingUtil;
import org.jeecg.modules.xslmes.constant.MesXslPrintConstants;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialEntry;
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialEntryService;
import org.jeecg.modules.xslmes.service.MesXslStompNotifyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
/**
* @Description: 原料入场记录
@@ -40,6 +62,16 @@ public class MesXslRawMaterialEntryController extends JeecgController<MesXslRawM
private IMesXslRawMaterialEntryService mesXslRawMaterialEntryService;
@Autowired
private MesXslStompNotifyService stompNotify;
@Autowired
private PrintServerEnvironmentService printServerEnvironmentService;
@Autowired
private PrintServerPdfJobService printServerPdfJobService;
@Autowired
private IPrintBizTemplateBindService printBizTemplateBindService;
@Autowired
private IPrintTemplateService printTemplateService;
@Autowired
private ObjectMapper objectMapper;
@Operation(summary = "原料入场记录-分页列表查询")
@GetMapping(value = "/list")
@@ -115,6 +147,78 @@ public class MesXslRawMaterialEntryController extends JeecgController<MesXslRawM
return Result.OK(mesXslRawMaterialEntry);
}
@Operation(summary = "原料入场记录-查询可用打印机")
@GetMapping(value = "/queryPrinters")
@RequiresPermissions(
value = {"xslmes:mes_xsl_raw_material_entry:list", "xslmes:mes_xsl_raw_material_entry:edit"},
logical = Logical.OR)
public Result<Map<String, Object>> queryPrinters() {
return Result.OK(printServerEnvironmentService.buildPrinterQueryResult());
}
/**
* 根据业务打印绑定生成模板 JSON + 映射后的 printData供前端生成 PDF 后调用 printPdf
*/
@Operation(summary = "原料入场记录-准备原生打印数据")
@GetMapping(value = "/prepareNativePrint")
@RequiresPermissions("xslmes:mes_xsl_raw_material_entry:edit")
public Result<Map<String, Object>> prepareNativePrint(@RequestParam(name = "id") String id) {
try {
MesXslRawMaterialEntry entry = mesXslRawMaterialEntryService.getById(id);
if (entry == null) {
return Result.error("未找到原料入场记录");
}
PrintBizTemplateBind bind =
printBizTemplateBindService.getByBizCode(MesXslPrintConstants.RAW_MATERIAL_ENTRY_PERM_ID);
if (bind == null) {
return Result.error("请先在「业务打印绑定」中配置原料入场记录与打印模板");
}
PrintTemplate tpl = printTemplateService.getById(bind.getTemplateId());
if (tpl == null) {
return Result.error("绑定的打印模板不存在");
}
ArrayNode mapping = PrintBizDataMappingUtil.parseMappingArray(bind.getFieldMappingJson());
JsonNode bizRoot = objectMapper.valueToTree(entry);
ObjectNode printData = PrintBizDataMappingUtil.mapBizToPrintData(bizRoot, mapping);
Map<String, Object> out = new HashMap<>(8);
out.put("entryId", entry.getId());
out.put("templateCode", bind.getTemplateCode());
out.put("templateJson", tpl.getTemplateJson());
out.put("paperWidthMm", tpl.getPaperWidthMm());
out.put("paperHeightMm", tpl.getPaperHeightMm());
out.put("paperOrientation", tpl.getPaperOrientation());
out.put("printData", objectMapper.convertValue(printData, Map.class));
return Result.OK(out);
} catch (Exception e) {
log.error("原料入场记录准备打印数据失败 id={}", id, e);
return Result.error("准备打印数据失败: " + e.getMessage());
}
}
@AutoLog(value = "原料入场记录-PDF后端打印")
@Operation(summary = "原料入场记录-PDF后端打印")
@PostMapping(value = "/printPdf")
@RequiresPermissions("xslmes:mes_xsl_raw_material_entry:edit")
public Result<String> printPdf(@RequestBody Map<String, Object> body) {
String id = String.valueOf(body.getOrDefault("id", "")).trim();
String printerName = String.valueOf(body.getOrDefault("printerName", "")).trim();
String pdfBase64 = String.valueOf(body.getOrDefault("pdfBase64", "")).trim();
String fileName = String.valueOf(body.getOrDefault("fileName", "")).trim();
if (StringUtils.isBlank(id)) {
return Result.error("id 不能为空");
}
MesXslRawMaterialEntry entry = mesXslRawMaterialEntryService.getById(id);
if (entry == null) {
return Result.error("未找到原料入场记录");
}
String prefix =
StringUtils.isNotBlank(entry.getBarcode()) ? entry.getBarcode() : entry.getId();
String fn =
StringUtils.isNotBlank(fileName) ? fileName : ("原料入场记录-" + prefix + ".pdf");
return printServerPdfJobService.submitPdfBase64(
printerName, pdfBase64, fn, "RAW_ENTRY_" + prefix);
}
@RequiresPermissions("xslmes:mes_xsl_raw_material_entry:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, MesXslRawMaterialEntry mesXslRawMaterialEntry) {