From 4cf5d44757217262f0ac3571174b1eb42c5338d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BD=8A?= <23> Date: Sun, 16 Aug 2026 18:05:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../upms/controller/DocxTemplateController.java | 105 +++++++++++++++++++-- .../AssociationActivitiesController.java | 59 ++++++------ .../plugin/active/ActivityInfoDetailsPlugin.java | 12 +-- .../plugin/active/ActivitySignConfigPlugin.java | 15 ++- zz-resource/quotation_template.docx | Bin 0 -> 12112 bytes 5 files changed, 145 insertions(+), 46 deletions(-) create mode 100644 zz-resource/quotation_template.docx diff --git a/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/controller/DocxTemplateController.java b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/controller/DocxTemplateController.java index e9659fe..26cd9d5 100644 --- a/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/controller/DocxTemplateController.java +++ b/application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/controller/DocxTemplateController.java @@ -1,11 +1,17 @@ package apelet.tenantadmin.upms.controller; import apelet.common.core.exception.MyRuntimeException; +import apelet.common.core.object.ObjectCollection; import apelet.common.core.object.ObjectValue; -import apelet.common.core.object.TokenData; +import apelet.common.core.object.ResponseResult; import apelet.common.generator.utils.OrmGenDataSourceUtil; import apelet.common.online.service.OnlineDictService; +import apelet.common.orm.impl.Filter; +import apelet.common.orm.impl.Selector; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.IoUtil; +import cn.hutool.poi.excel.ExcelReader; +import cn.hutool.poi.excel.ExcelUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; @@ -14,9 +20,12 @@ import org.apache.commons.lang3.StringUtils; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.xwpf.usermodel.*; import org.docx4j.Docx4J; +import org.docx4j.fonts.IdentityPlusMapper; +import org.docx4j.fonts.PhysicalFonts; import org.docx4j.openpackaging.packages.WordprocessingMLPackage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.io.*; @@ -25,11 +34,10 @@ import java.net.URL; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; @RestController @RequestMapping("/api/template") @@ -76,7 +84,7 @@ public class DocxTemplateController { hashMap.put("name", objectValue.getString("name")); hashMap.put("type", dictMap.get(String.valueOf(objectValue.get("type", "")))); hashMap.put("number", objectValue.getString("number")); - hashMap.put("create_time", objectValue.getString("create_time")); + hashMap.put("create_time", objectValue.getString("create_time").substring(0, 10)); hashMap.put("qty", objectValue.getString("qty")); String signatureImage = user.getString("signature_image"); @@ -108,6 +116,8 @@ public class DocxTemplateController { docxOut.close(); WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new ByteArrayInputStream(docxBytes)); + PhysicalFonts.discoverPhysicalFonts(); + wordMLPackage.setFontMapper(new IdentityPlusMapper()); pdfOut = new ByteArrayOutputStream(); Docx4J.toPDF(wordMLPackage, pdfOut); byte[] pdfBytes = pdfOut.toByteArray(); @@ -208,7 +218,6 @@ public class DocxTemplateController { } - private void replaceImageInParagraphs(XWPFDocument document, String placeholderKey, byte[] imageBytes, int width, int height) throws IOException, InvalidFormatException { String placeholder = "#{" + placeholderKey + "}"; for (XWPFParagraph paragraph : document.getParagraphs()) { @@ -257,4 +266,88 @@ public class DocxTemplateController { } } + + private static final Map HEADER_MAP = new LinkedHashMap<>(); + + static { + HEADER_MAP.put("名称", "name"); + HEADER_MAP.put("性别", "gender"); + HEADER_MAP.put("手机号码", "phone"); + HEADER_MAP.put("出生年月", "birth_date"); + HEADER_MAP.put("学历", "education"); + HEADER_MAP.put("民族", "nation"); + HEADER_MAP.put("政治面貌", "political_status"); + HEADER_MAP.put("身份证号码", "id_card"); + HEADER_MAP.put("毕业院校", "graduate_school"); + HEADER_MAP.put("所属专业", "major"); + HEADER_MAP.put("常住地", "permanent_address"); + } + + @PostMapping("/expertImport") + public ResponseResult expertImport(@RequestParam("file") MultipartFile file) { + List> dataList = new ArrayList<>(); + try (InputStream is = file.getInputStream()) { + ExcelReader reader = ExcelUtil.getReader(is); + // 第一行作为表头,key 为表头名称,自动兼容 xls/xlsx + List> rawList = reader.readAll(); + //学历 + Map educationDictMap = onlineDictService.getDictMap(2054094099727781888L); + educationDictMap = educationDictMap.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); + //政治面貌 + Map politicalDictMap = onlineDictService.getDictMap(2054098587905691648L); + politicalDictMap = politicalDictMap.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); + for (Map row : rawList) { + Map dataMap = new LinkedHashMap<>(); + + for (Map.Entry entry : row.entrySet()) { + String header = entry.getKey() == null ? "" : entry.getKey().trim(); + // 中文表头转英文,映射中没有的表头保留原值 + String key = HEADER_MAP.getOrDefault(header, header); + Object value = entry.getValue(); + dataMap.put(key, value); + if (key.equals("gender")) { + dataMap.put("gender", value.equals("男") ? "1" : "0"); + } + if (key.equals("education")) { + dataMap.put("education", educationDictMap.get(value.toString())); + } + if (key.equals("political_status")) { + dataMap.put("political_status", politicalDictMap.get(value.toString())); + } + if ("birth_date".equals(key)) { + if (value instanceof Date) { + value = DateUtil.formatDateTime((Date) value); + } else if (value instanceof String && StringUtils.isNotBlank((String) value)) { + value = DateUtil.formatDateTime(DateUtil.parse((String) value)); + } + dataMap.put(key, value); + } + } + dataMap.put("billstatus", "A"); + dataMap.put("apply_time", DateUtil.formatDateTime(new Date())); + dataList.add(dataMap); + } + ObjectCollection expertManage = ormGenDataSourceUtil.query("expert_manage", new Filter(), new Selector()); + dataList.forEach(dataMap -> { + long count = expertManage.stream().filter(f -> f.get("id_card").equals(dataMap.get("id_card"))).count(); + if (count > 0) { + return; + } + ObjectValue value = new ObjectValue("expert_manage"); + value.setValues(dataMap); + try { + ormGenDataSourceUtil.addNew("expert_manage", value); + } catch (Exception e) { + e.printStackTrace(); + } + }); + + } catch (IOException e) { + throw new MyRuntimeException("文件解析失败: " + e.getMessage()); + } + return ResponseResult.success("导入成功"); + } + } \ No newline at end of file diff --git a/common/common-association/src/main/java/apelet/association/controller/AssociationActivitiesController.java b/common/common-association/src/main/java/apelet/association/controller/AssociationActivitiesController.java index 91060c2..1c8918a 100644 --- a/common/common-association/src/main/java/apelet/association/controller/AssociationActivitiesController.java +++ b/common/common-association/src/main/java/apelet/association/controller/AssociationActivitiesController.java @@ -54,50 +54,51 @@ public class AssociationActivitiesController { } Integer type = jsonObject.getInteger("type"); - Filter filter = new Filter(); - filter.add(new FilterItem("unit_name", FilterItem.equals, signInUnit)); - ObjectCollection collection = ormGenDataSourceUtil.query("membership_apply", filter, new Selector()); - - if (collection == null || collection.isEmpty()) { - return ResponseResult.error("500", "签到单位不存在, 请检查签到单位!!!"); - } - - ObjectCollection managerCollection = ormGenDataSourceUtil.query("membership_manager", new Filter(), new Selector()); - List> managerList = DataTransformationUtil.objectCollectionToList(managerCollection); - Map> mapMap = managerList.stream().collect(Collectors.toMap(map -> String.valueOf(map.get("id")), map -> map, (oldValue, newValue) -> oldValue)); - - ObjectValue member = null; - for (int i = 0; i < collection.size(); i++) { - ObjectValue object = collection.getObject(i); - ObjectValue manger = object.getObjectValue("membership_manger_id"); - Map map = mapMap.get(manger != null && manger.get("id") != null ? manger.get("id") : ""); - Object phone = map.get("phone"); - if (ObjectUtil.equal(phone, phoneNumber)) { - member = object; - } - } - if (member == null) { - return ResponseResult.error("500", signInUnit + " 签到单位下签到人不存在!!!"); - } +// Filter filter = new Filter(); +// filter.add(new FilterItem("unit_name", FilterItem.equals, signInUnit)); +// ObjectCollection collection = ormGenDataSourceUtil.query("membership_apply", filter, new Selector()); +// +// if (collection == null || collection.isEmpty()) { +// return ResponseResult.error("500", "签到单位不存在, 请检查签到单位!!!"); +// } +// +// ObjectCollection managerCollection = ormGenDataSourceUtil.query("membership_manager", new Filter(), new Selector()); +// List> managerList = DataTransformationUtil.objectCollectionToList(managerCollection); +// Map> mapMap = managerList.stream().collect(Collectors.toMap(map -> String.valueOf(map.get("id")), map -> map, (oldValue, newValue) -> oldValue)); +// +// ObjectValue member = null; +// for (int i = 0; i < collection.size(); i++) { +// ObjectValue object = collection.getObject(i); +// ObjectValue manger = object.getObjectValue("membership_manger_id"); +// Map map = mapMap.get(manger != null && manger.get("id") != null ? manger.get("id") : ""); +// Object phone = map.get("phone"); +// if (ObjectUtil.equal(phone, phoneNumber)) { +// member = object; +// } +// } +// if (member == null) { +// return ResponseResult.error("500", signInUnit + " 签到单位下签到人不存在!!!"); +// } if (type == 1) { //签到 ObjectValue value = new ObjectValue("check_in_out"); value.put("name", signInPerson); value.put("phone", phoneNumber); - value.put("membership_id", member); +// value.put("membership_id", member); value.put("create_time", new Date()); value.put("create_time", new Date()); value.put("parent_id", activityId); value.put("check_in", 1); ormGenDataSourceUtil.addNew(value.getTableName(), value); } + if (type == 2) { //签退 - filter = new Filter(); - filter.add(new FilterItem("membership_id", FilterItem.equals, member.get("id"))); + Filter filter = new Filter(); +// filter.add(new FilterItem("membership_id", FilterItem.equals, member.get("id"))); filter.add(new FilterItem("parent_id", FilterItem.equals, activityId)); filter.add(new FilterItem("check_in", FilterItem.equals, 1)); - collection = ormGenDataSourceUtil.query("check_in_out", filter, new Selector()); + ObjectCollection collection = ormGenDataSourceUtil.query("check_in_out", filter, new Selector()); if (collection != null && !collection.isEmpty()) { ObjectValue object = collection.getObject(0); object.put("check_out", 1); diff --git a/common/common-association/src/main/java/apelet/association/plugin/active/ActivityInfoDetailsPlugin.java b/common/common-association/src/main/java/apelet/association/plugin/active/ActivityInfoDetailsPlugin.java index 5867c00..26aaca6 100644 --- a/common/common-association/src/main/java/apelet/association/plugin/active/ActivityInfoDetailsPlugin.java +++ b/common/common-association/src/main/java/apelet/association/plugin/active/ActivityInfoDetailsPlugin.java @@ -130,10 +130,10 @@ public class ActivityInfoDetailsPlugin extends ListPlugin { // 生成报名二维码 if (widgetVariableName.equals("button1786587153460")) { String registrationQr = objectValue.getString("registration_qr"); - if (StringUtils.isNotEmpty(registrationQr)) { - this.showErrorMessage("当前已存在报名二维码, 请勿重复生成!!!"); - return; - } +// if (StringUtils.isNotEmpty(registrationQr)) { +// this.showErrorMessage("当前已存在报名二维码, 请勿重复生成!!!"); +// return; +// } OnlineEventPluginExecuteDto dto = getDto(); String savePath = System.getProperty("user.dir") + "\\zz-resource\\qrcode"; File QRFile = null; @@ -146,9 +146,9 @@ public class ActivityInfoDetailsPlugin extends ListPlugin { String url = "http://58.48.135.5:8069" + "/#/?" + "loginName=" + "admin" + "&password=" + "123456" + - "&entryId=" + "2087710350152568832" + + "&entryId=" + "2087413611113746432" + "&bindType=" + "1" + - "&onlineFormId=" + "2048951917157027840" + + "&onlineFormId=" + "2087385700075835392" + "&activeId=" + id; byte[] checkInQr = qrCodeUtil.generateQrCode(url, 350, 350); diff --git a/common/common-association/src/main/java/apelet/association/plugin/active/ActivitySignConfigPlugin.java b/common/common-association/src/main/java/apelet/association/plugin/active/ActivitySignConfigPlugin.java index 4c40e69..cf9cd36 100644 --- a/common/common-association/src/main/java/apelet/association/plugin/active/ActivitySignConfigPlugin.java +++ b/common/common-association/src/main/java/apelet/association/plugin/active/ActivitySignConfigPlugin.java @@ -27,6 +27,8 @@ import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.Map; /** @@ -113,20 +115,23 @@ public class ActivitySignConfigPlugin extends ListPlugin { File checkOutFile = null; File checkInFile = null; try { - Object activityId = objectValue.get("id"); - Object activityName = objectValue.get("name"); + Map parentParams = getDto().getParentParams(); + Object activityId = parentParams.get("id"); + ObjectValue value = ormGenDataSourceUtil.queryOne("association_activity", activityId); + String name = value.getString("name"); OnlineDatasource onlineDatasource = onlineDatasourceService.getById(model.getDatasourceId()); OnlineTable table = onlineTableService.getOnlineTableFromCache(onlineDatasource.getMasterTableId()); - - String checkIn = url + "/#/pages/login/routerHdView?activityId=" + activityId + "&activityName=" + activityName + "&type=" + 1; + // 中文活动名称做 URL 编码,保证扫码 URL 为纯 ASCII;前端 decodeURIComponent 后仍是原中文 + String encodedName = URLEncoder.encode(name, StandardCharsets.UTF_8.name()); + String checkIn = url + "/#/pages/login/routerHdView?activityId=" + activityId + "&activityName=" + encodedName + "&type=1"; byte[] checkInQr = qrCodeUtil.generateQrCode(checkIn, 350, 350); checkInFile = MyFileUtil.writeToFile(checkInQr, savePath, "qrcode-" + System.currentTimeMillis() + ".png"); MultipartFile checkInMultipart = MyFileUtil.readFileAsMultipartFile(checkInFile, "image/png"); UploadResponseInfo checkInUpload = myFileUtil.uploadMyFile(table, "sign_in_code", true, checkInMultipart); this.setWidgetAttribute("signInCode", AttributeEnum.VALUE_CHANGE, checkInUpload); - String checkOut = url + "#/pages/login/routerHdView?activityId=" + activityId + "&activityName=" + activityName + "&type=" + 2; + String checkOut = url + "/#/pages/login/routerHdView?activityId=" + activityId + "&activityName=" + encodedName + "&type=2"; byte[] checkOutQr = qrCodeUtil.generateQrCode(checkOut, 300, 300); checkOutFile = MyFileUtil.writeToFile(checkOutQr, savePath, "qrcode-" + System.currentTimeMillis() + ".png"); MultipartFile checkOutMultipart = MyFileUtil.readFileAsMultipartFile(checkOutFile, "image/png"); diff --git a/zz-resource/quotation_template.docx b/zz-resource/quotation_template.docx new file mode 100644 index 0000000000000000000000000000000000000000..07147ad5d30a3d0b665ea4cb17cde4c1bfb76dfd GIT binary patch literal 12112 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 literal 0 HcmV?d00001