From a09dd826498cb42bad973b0926ba27e02456c0e9 Mon Sep 17 00:00:00 2001 From: HanLong <404402223@qq.com> Date: Sat, 28 Feb 2026 16:30:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:[=E8=B5=84=E6=BA=90=E5=BA=93=E7=AE=A1?= =?UTF-8?q?=E7=90=86][=E8=AF=95=E5=89=82=E7=AE=A1=E7=90=86]=E5=AF=BC?= =?UTF-8?q?=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/hxhq/business/controller/SjController.java | 37 ++++ .../com/hxhq/business/utils/lang/SjJcnrUtil.java | 167 +++++++++++++++++ .../hxhq/business/utils/pdf/resource/SjPdf.java | 204 +++++++++++++++++++++ 3 files changed, 408 insertions(+) create mode 100644 hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/utils/lang/SjJcnrUtil.java create mode 100644 hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/utils/pdf/resource/SjPdf.java diff --git a/hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/controller/SjController.java b/hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/controller/SjController.java index b2f286f..ac5cf00 100644 --- a/hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/controller/SjController.java +++ b/hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/controller/SjController.java @@ -16,9 +16,12 @@ import com.hxhq.business.service.ISjTzService; import com.hxhq.business.service.ISjJcgjService; import com.hxhq.business.service.IStudySubjectService; import com.hxhq.business.utils.JctUtil; +import com.hxhq.business.utils.pdf.PdfExportUtil; +import com.hxhq.common.security.annotation.Logical; import com.hxhq.common.security.annotation.RequiresPermissions; import com.hxhq.common.security.utils.SecurityUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import com.hxhq.common.core.web.controller.BaseController; @@ -45,6 +48,16 @@ public class SjController extends BaseController @Autowired private ISjTzService sjTzService; + /** + * 上传文件存储在本地的根路径 + */ + @Value("${file.path}") + private String localFilePath; + /** + * 资源映射路径 前缀 + */ + @Value("${file.prefix}") + public String localFilePrefix; /** * 试验物资列表 @@ -70,6 +83,30 @@ public class SjController extends BaseController } /** + * 导出 + */ + @RequiresPermissions(value={"business:resource:sj:xq","business:archive:sj:xq"}, logical= Logical.OR) + @GetMapping(value = "/exportDetail") + public AjaxResult exportDetail(Long id,String lang) { + SjJcgj sjJcgj = new SjJcgj(); + sjJcgj.setSjId(id); + List sjJcgjList = sjJcgjService.queryList(sjJcgj); + + SjTz sjTz = new SjTz(); + sjTz.setSjId(id); + List sjTzList = sjTzService.queryList(sjTz); + return AjaxResult.success(localFilePrefix + PdfExportUtil.export( + "com.hxhq.business.utils.pdf.resource.SjPdf", + "exportDetail", + sjService.getInfo(id), + sjTzList, + sjJcgjList, + lang, + localFilePath)); + } + + + /** * 台账列表 */ @GetMapping("/tzList") diff --git a/hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/utils/lang/SjJcnrUtil.java b/hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/utils/lang/SjJcnrUtil.java new file mode 100644 index 0000000..f528556 --- /dev/null +++ b/hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/utils/lang/SjJcnrUtil.java @@ -0,0 +1,167 @@ +package com.hxhq.business.utils.lang; + +import com.hxhq.business.utils.JctUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author tanfei + */ +public class SjJcnrUtil { + private static final Logger logger = LoggerFactory.getLogger(SjJcnrUtil.class.getName()); + private static HashMap mapLang=new HashMap<>(); + static { + mapLang.put("入库","In Storage"); + mapLang.put("未入库","Not in Storage"); + mapLang.put("已发放","In Use"); + mapLang.put("已锁定","Locked"); + mapLang.put("待归档","Pending Archiving"); + mapLang.put("归档","Archived"); + mapLang.put("待解档","Pending De-archiving"); + mapLang.put("借阅开始时间","Checkout Start Date"); + mapLang.put("借阅结束时间","Checkout End Date"); + mapLang.put("处置","Dispose"); + mapLang.put("处置方式","Dispose Method"); + mapLang.put("处置原因","Reason"); + mapLang.put("处置量","Amount"); + mapLang.put("处置人","Operator"); + mapLang.put("使用","Usage"); + mapLang.put("配制完成","Configuration completed"); + mapLang.put("复核人","Reviewer"); + mapLang.put("监督人","Supervisor"); + mapLang.put("钥匙1领取人","Key 1 User"); + mapLang.put("钥匙2领取人","Key 2 User"); + mapLang.put("发放人","Issuer"); + mapLang.put("发放人2","Issuer 2"); + mapLang.put("出库量","Out Amount"); + mapLang.put("转移条件","Transfer Condition"); + mapLang.put("出库毛重","Check-out Gross Weight"); + mapLang.put("入库毛重","Check-in Gross Weight"); + mapLang.put("使用量","Usage Amount"); + mapLang.put("归还人1","Returner 1"); + mapLang.put("归还人2","Returner 2"); + mapLang.put("库管员1","Warehouse Keeper 1"); + mapLang.put("库管员2","Warehouse Keeper 2"); + mapLang.put("签名人1","Signed By 1"); + mapLang.put("签名人2","Signed By 2"); + mapLang.put("申请备注","Apply Comment"); + mapLang.put("审核备注","Approve Comment"); + mapLang.put("存储条件","Storage Condition"); + mapLang.put("存储位置","Storage Location"); + mapLang.put("有效周期","Validity Period"); + mapLang.put("使用人","User"); + mapLang.put("领取/归还人","Recipient/Returner"); + mapLang.put("发放/接收人","Issuer/Receiver"); + mapLang.put("操作类型","Action"); + mapLang.put("操作量","Amount"); + mapLang.put("备注/原因","Comment/Reason"); + mapLang.put("操作时间","Datetime"); + mapLang.put("名称","Name"); + mapLang.put("编号","ID"); + mapLang.put("浓度/含量/纯度","Concentration/Purity"); + mapLang.put("批号","Batch Num"); + mapLang.put("规格","Specification"); + mapLang.put("库存量","Amount"); + mapLang.put("来源","Source"); + mapLang.put("失效日期","Expiration"); + mapLang.put("配制日期","Formulation Date"); + mapLang.put("制剂状态","Status"); + mapLang.put("所属表单","In Record"); + mapLang.put("表单所属试验","From Study"); + mapLang.put("表单所属人","By User"); + mapLang.put("表单所属部门","Department"); + mapLang.put("基本信息","Information"); + mapLang.put("表单信息","Record Information"); + mapLang.put("稽查轨迹","Track Record"); + mapLang.put("麻精药台账","Controlled Drug Table"); + mapLang.put("备注","Comment"); + mapLang.put("原因","Reason"); + mapLang.put("签名人","Signed By"); + + + + mapLang.put("申请解档","Apply for De-archiving"); + mapLang.put("申请借阅","Apply for Check-out"); + mapLang.put("申请归档","Apply for Archiving"); + mapLang.put("锁定麻精药","Lock Controlled Drug"); + mapLang.put("解锁麻精药","Unlock Controlled Drug"); + mapLang.put("处置药剂","Dispose Substance"); + mapLang.put("处置容器","Dispose Container"); + mapLang.put("钥匙发放","Issue Key"); + mapLang.put("申请编辑","Apply Edit"); + mapLang.put("同意编辑","Approve Edit"); + mapLang.put("拒绝编辑","Reject Edit"); + mapLang.put("修改库存申请","Apply Change Inventory"); + mapLang.put("同意修改库存","Approve Change Inventory"); + mapLang.put("拒绝修改库存","Reject Change Inventory"); + mapLang.put("归还","Return"); + mapLang.put("领取发放","Distribution"); + mapLang.put("存储","Storage"); + mapLang.put("取出","Take Out"); + mapLang.put("确认归还","Confirm Check-in"); + mapLang.put("到期自动归还","到期自动归还"); + + mapLang.put("表单名称","Preset Name"); + mapLang.put("锁定发放记录","Lock Record"); + mapLang.put("解锁发放记录","Unlock Record"); + mapLang.put("麻精药入库","Controlled Drug Check-in"); + mapLang.put("目的","Purpose"); + mapLang.put("麻精药详情","Controlled Drug Information"); + + mapLang.put("入库位置","Check-in Location"); + mapLang.put("入库条件","Check-in Condition"); + mapLang.put("同意归档","Approve Archiving"); + mapLang.put("拒绝归档","Reject Archiving"); + mapLang.put("同意解档","Approve De-archiving"); + mapLang.put("拒绝解档","Reject De-archiving"); + mapLang.put("同意借阅","Approve Check-out"); + mapLang.put("拒绝借阅","Reject Check-out"); + + } + + public static void main(String[] args) { + Map formData = new LinkedHashMap<>(); + formData.put("申请备注", "1111"); + formData.put("审核备注", "22"); + logger.info(getJcnrEn(formData)); + } + /** + * 获取英文 + * @param qmyy + * @return + */ + public static String getEn(String qmyy) { + return mapLang.get(qmyy); + } + + /** + * 获取稽查内容英文 + * @param map + * @return + */ + public static String getJcnrEn(Map map) { + Map result =new LinkedHashMap<>(); + for (Map.Entry entry : map.entrySet()) { + result.put(mapLang.get(entry.getKey()),entry.getValue()); + } + return JctUtil.formatStr(result); + } + + /** + * 获取稽查内容英文 + * @param map + * @return + */ + public static Map getMapEn(Map map) { + Map result =new LinkedHashMap<>(); + for (Map.Entry entry : map.entrySet()) { + result.put(mapLang.get(entry.getKey()),entry.getValue()); + } + return result; + } + +} diff --git a/hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/utils/pdf/resource/SjPdf.java b/hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/utils/pdf/resource/SjPdf.java new file mode 100644 index 0000000..caefb1c --- /dev/null +++ b/hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/utils/pdf/resource/SjPdf.java @@ -0,0 +1,204 @@ +package com.hxhq.business.utils.pdf.resource; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.hxhq.business.domain.*; +import com.hxhq.business.dto.gsp.GspDto; +import com.hxhq.business.dto.sj.SjListDto; +import com.hxhq.business.enums.zykgl.ZjztEnum; +import com.hxhq.business.utils.lang.GyzjJcnrUtil; +import com.hxhq.business.utils.lang.SjJcnrUtil; +import com.hxhq.business.utils.pdf.PdfBaseUtil; +import com.hxhq.business.utils.pdf.PdfExportUtil; +import com.hxhq.common.core.utils.StringUtils; +import com.hxhq.common.security.utils.SecurityUtils; +import com.hxhq.system.api.model.LoginUser; +import com.itextpdf.text.*; +import com.itextpdf.text.pdf.BaseFont; +import com.itextpdf.text.pdf.PdfPCell; +import com.itextpdf.text.pdf.PdfPTable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.List; +import java.util.*; + +/** + * 试剂pdf导出详情 + * + * @author HanLong + */ +public class SjPdf { + private static final Logger logger = LoggerFactory.getLogger(SjPdf.class.getName()); + public String language="zh"; + /** + * 导出 + * + * @param sj + * @return + */ + public String exportDetail(SjListDto sj, List tzList, List jcgjList, String lang, String localFilePath) { + language=lang; + Document document = null; + FileOutputStream fos = null; + String filePath = PdfBaseUtil.getFilePath(localFilePath,"Sj"); + try { + String sign = "hxhq"; + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser != null) { + sign = loginUser.getSysUser().getNickName(); + } + document = PdfBaseUtil.init(document, fos, filePath, sign + PdfExportUtil.parseDateToStr(new Date()), getName("给药制剂详情"),false); + // 基本信息 + PdfBaseUtil.addUnderlinedTitle(document, getName("基本信息"), 10, true); + Map formData1 = new LinkedHashMap<>(); + formData1.put(getName("名称"), sj.getMc()); + formData1.put(getName("编号"), sj.getBh()); + formData1.put(getName("批号"), sj.getPh()); + formData1.put(getName("规格"), sj.getGg()); + formData1.put(getName("浓度"), sj.getNd() + sj.getNddw()); + formData1.put(getName("库存量"), sj.getKc() + sj.getKcdw()); + formData1.put(getName("来源"), sj.getLy()); + formData1.put(getName("存储条件"), sj.getCctj()); + formData1.put(getName("存储位置"), sj.getCcwz()); + formData1.put(getName("有效周期"), sj.getYxzq() + sj.getYxzqdw()); + formData1.put(getName("失效日"), PdfExportUtil.parseDateToStr(sj.getSxr())); + formData1.put(getName("配制日期"), PdfExportUtil.parseDateToStr(sj.getPzrq())); + PdfBaseUtil.addFormTableColumns(document, formData1, 2); + // 表单信息 + PdfBaseUtil.addUnderlinedTitle(document, getName("表单信息"), 10, true); + Map formData3 = new LinkedHashMap<>(); + formData3.put(getName("所属表单"), sj.getFormName()); + formData3.put(getName("表单所属试验"), sj.getStudyName()); + formData3.put(getName("表单所属人"), sj.getFormUserName()); + formData3.put(getName("表单所属部门"), sj.getDeptName()); + PdfBaseUtil.addFormTableColumns(document, formData3, 2); + PdfBaseUtil.addUnderlinedTitle(document, getName("试剂台账") , 10, true); + // 台账 + addTz(document, tzList, lang); + PdfBaseUtil.addUnderlinedTitle(document, getName("稽查轨迹") , 10, true); + //稽查轨迹 + addJcgj(document, jcgjList, lang); + logger.info("生成成功:{}", filePath); + } catch (Exception e) { + logger.error("生成失败", e); + throw new RuntimeException("生成失败: " + e.getMessage()); + } finally { + if (document != null) { + document.close(); + } + if (fos != null) { + try { + fos.close(); + } catch (IOException e) { + logger.error("关闭文件流失败", e); + } + } + } + return filePath; + } + + /** + * 台账 + * + * @param document + * @param tzList + * @throws IOException + * @throws DocumentException + */ + public void addTz(Document document, List tzList, String lang) throws IOException, DocumentException { + + // 9. 表头 + BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); + Font headerFont = new Font(bfChinese, 8, Font.NORMAL); + Font contentFont = new Font(bfChinese, 8, Font.NORMAL); + // 8. 创建表格 + PdfPTable table = new PdfPTable(8); + table.setWidthPercentage(100); + String[] headers = {getName("签名人"),getName("操作类型"),getName("操作量"),getName("备注/原因"),getName("操作时间")}; + for (String header : headers) { + PdfPCell cell = new PdfPCell(new Phrase(header, headerFont)); + cell.setHorizontalAlignment(Element.ALIGN_CENTER); + cell.setPadding(8); + cell.setBorderWidth(1); + table.addCell(cell); + } + int rowNum = 0; + for (SjTz sjTz : tzList) { + // 交替行颜色 + if (rowNum % 2 == 0) { + table.getDefaultCell().setBackgroundColor(BaseColor.WHITE); + } else { + table.getDefaultCell().setBackgroundColor(BaseColor.WHITE); + } + table.addCell(PdfBaseUtil.createCell(sjTz.getQmrMc(), contentFont)); + table.addCell(PdfBaseUtil.createCell(sjTz.getQmyy(), contentFont)); + table.addCell(PdfBaseUtil.createCell(sjTz.getCzl() + sjTz.getCzldw(), contentFont)); + table.addCell(PdfBaseUtil.createCell(sjTz.getRemark(), contentFont)); + table.addCell(PdfBaseUtil.createCell(PdfExportUtil.parseDateToStr(sjTz.getCreateTime()), contentFont)); + rowNum++; + } + document.add(table); + } + + /** + * 稽查轨迹 + * + * @param document + * @param jcgjList + * @throws IOException + * @throws DocumentException + */ + public void addJcgj(Document document, List jcgjList, String lang) throws IOException, DocumentException { + for (SjJcgj jcgj : jcgjList) { + StringJoiner result = new StringJoiner(", "); + if ("en".equals(lang)) { + PdfBaseUtil.addUnderlinedTitle(document, PdfExportUtil.parseDateToStr(jcgj.getCreateTime())+ " " + jcgj.getJcmcEn(), 10, false); + if (StringUtils.isNoneBlank(jcgj.getJcnrEn())) { + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonArray = mapper.readTree(jcgj.getJcnrEn()); + for (JsonNode node : jsonArray) { + if (node.get("name") != null) { + String name = node.get("name").asText(); + String value = node.get("value")!=null? node.get("value").asText():""; + result.add(name + ":" + value); + } + } + } + } else { + PdfBaseUtil.addUnderlinedTitle(document, PdfExportUtil.parseDateToStr(jcgj.getCreateTime())+ " " + jcgj.getJcmc(), 10, false); + if (StringUtils.isNoneBlank(jcgj.getJcnr())) { + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonArray = mapper.readTree(jcgj.getJcnr()); + for (JsonNode node : jsonArray) { + if (node.get("name") != null) { + String name = node.get("name").asText(); + String value =node.get("value")!=null? node.get("value").asText():""; + result.add(name + ":" + value); + } + } + } + } + if (StringUtils.isNoneBlank(jcgj.getRemark())) { + result.add(getName("备注")+":" + jcgj.getRemark()); + } + if (StringUtils.isNoneBlank(jcgj.getQmrMc())) { + result.add(getName("签名人")+":" + jcgj.getQmrMc()); + } + PdfBaseUtil.addUnderlinedTitle(document, result.toString(), 10, false); + } + } + + /** + * 获取名称 + * @param name + * @return + */ + public String getName(String name){ + return "en".equals(language) ? SjJcnrUtil.getEn(name) : name; + } + + +}