新增打印模板绑定功能,支持业务与打印模板的映射配置。实现打印模板的增删改查操作,优化打印数据的生成逻辑,提升打印模板的灵活性和用户体验。同时,新增打印机查询接口,增强打印服务的可用性和实时性。

This commit is contained in:
geht
2026-05-13 15:49:51 +08:00
parent 210f3614ea
commit c3f8190537
32 changed files with 2323 additions and 229 deletions

View File

@@ -18,5 +18,11 @@
<groupId>org.jeecgframework.boot3</groupId>
<artifactId>jeecg-boot-base-core</artifactId>
</dependency>
<!-- 复用打印模板模块打印机枚举、业务绑定、PDF 提交队列 -->
<dependency>
<groupId>org.jeecgframework.boot3</groupId>
<artifactId>jeecg-system-biz</artifactId>
<version>${jeecgboot.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -9,9 +9,18 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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 org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
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.util.PrintBizDataMappingUtil;
import org.jeecg.modules.xslmes.constant.MesXslCustomerBizStatus;
import org.jeecg.modules.xslmes.entity.MesXslCustomer;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialCard;
@@ -33,6 +42,8 @@ import org.jeecg.modules.xslmes.service.MesXslStompNotifyService;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
@@ -59,6 +70,9 @@ public class MesXslDesktopAnonController {
private final IMesXslWarehouseService warehouseService;
private final IMesXslWarehouseAreaService warehouseAreaService;
private final MesXslStompNotifyService stompNotify;
private final IPrintBizTemplateBindService printBizTemplateBindService;
private final IPrintTemplateService printTemplateService;
private final ObjectMapper objectMapper;
// ═══════════════════════════ 车辆管理 ═══════════════════════════
@@ -606,6 +620,34 @@ 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")
public Result<Map<String, Object>> rawMaterialCardAnonPrepareNativePrint(@RequestParam(name = "id") String id) {
try {
MesXslRawMaterialCard card = rawMaterialCardService.getById(id);
if (card == null) return Result.error("未找到原材料卡片");
PrintBizTemplateBind bind = printBizTemplateBindService.getByBizCode(RAW_MATERIAL_CARD_BIZ_CODE);
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(card);
ObjectNode printData = PrintBizDataMappingUtil.mapBizToPrintData(bizRoot, mapping);
Map<String, Object> out = new HashMap<>(8);
out.put("cardId", card.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

@@ -1,27 +1,48 @@
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.MesXslRawMaterialCard;
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialCardService;
import org.jeecg.modules.xslmes.service.MesXslStompNotifyService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.entity.MesXslRawMaterialCard;
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialCardService;
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: 原材料卡片
@@ -34,10 +55,24 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
@RequestMapping("/xslmes/mesXslRawMaterialCard")
@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
private MesXslStompNotifyService stompNotify;
@Autowired
private PrintServerEnvironmentService printServerEnvironmentService;
@Autowired
private PrintServerPdfJobService printServerPdfJobService;
@Autowired
private IPrintBizTemplateBindService printBizTemplateBindService;
@Autowired
private IPrintTemplateService printTemplateService;
@Autowired
private ObjectMapper objectMapper;
/**
* 分页列表查询
@@ -122,6 +157,87 @@ public class MesXslRawMaterialCardController extends JeecgController<MesXslRawMa
return Result.OK("批量删除成功!");
}
/**
* 查询可用打印机(与 /print/template/queryPrinters 返回结构一致)
*/
@Operation(summary = "原材料卡片-查询可用打印机")
@GetMapping(value = "/queryPrinters")
/** 有 list 可进页拉打印机;有 edit 可打印拉打印机,避免单权限缺另一项时 403 */
@RequiresPermissions(
value = {"xslmes:mes_xsl_raw_material_card:list", "xslmes:mes_xsl_raw_material_card:edit"},
logical = Logical.OR)
public Result<Map<String, Object>> queryPrinters() {
return Result.OK(printServerEnvironmentService.buildPrinterQueryResult());
}
/**
* 根据业务打印绑定生成模板 JSON + 映射后的 printData供前端生成 PDF 后调用 printPdf
*/
@Operation(summary = "原材料卡片-准备原生打印数据")
@GetMapping(value = "/prepareNativePrint")
/** 与 printPdf 一致:准备模板与打印数据属于「打印」动作,使用 edit 权限 */
@RequiresPermissions("xslmes:mes_xsl_raw_material_card:edit")
public Result<Map<String, Object>> prepareNativePrint(@RequestParam(name = "id") String id) {
try {
MesXslRawMaterialCard card = mesXslRawMaterialCardService.getById(id);
if (card == null) {
return Result.error("未找到原材料卡片");
}
PrintBizTemplateBind bind =
printBizTemplateBindService.getByBizCode(RAW_MATERIAL_CARD_BIZ_CODE);
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(card);
ObjectNode printData = PrintBizDataMappingUtil.mapBizToPrintData(bizRoot, mapping);
Map<String, Object> out = new HashMap<>(8);
out.put("cardId", card.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());
}
}
/**
* 将前端生成的 PDF Base64 提交到服务器打印机(与 /print/template/directPrintPdf 一致)
*/
@AutoLog(value = "原材料卡片-PDF后端打印")
@Operation(summary = "原材料卡片-PDF后端打印")
@PostMapping(value = "/printPdf")
@RequiresPermissions("xslmes:mes_xsl_raw_material_card: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 不能为空");
}
MesXslRawMaterialCard card = mesXslRawMaterialCardService.getById(id);
if (card == null) {
return Result.error("未找到原材料卡片");
}
String prefix =
StringUtils.isNotBlank(card.getBarcode()) ? card.getBarcode() : card.getId();
String fn =
StringUtils.isNotBlank(fileName) ? fileName : ("原材料卡片-" + prefix + ".pdf");
return printServerPdfJobService.submitPdfBase64(
printerName, pdfBase64, fn, "RAW_CARD_" + prefix);
}
/**
* 通过id查询
*/