From ea426a13d99fd42c57636576a0cd903eb50a2322 Mon Sep 17 00:00:00 2001 From: myf Date: Thu, 20 Aug 2026 14:38:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=BD=92=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ElectronicJournalFormPlugin.java | 169 +++++++++++++++++++-- .../fileLibraryMange/FileLibrayListPlugin.java | 37 +++++ .../plugin/quotation/QuotationPlugin.java | 131 ++++++++++++++++ 3 files changed, 324 insertions(+), 13 deletions(-) diff --git a/common/common-association/src/main/java/apelet/association/plugin/electronicJournal/ElectronicJournalFormPlugin.java b/common/common-association/src/main/java/apelet/association/plugin/electronicJournal/ElectronicJournalFormPlugin.java index e7f04f4..4c9e479 100644 --- a/common/common-association/src/main/java/apelet/association/plugin/electronicJournal/ElectronicJournalFormPlugin.java +++ b/common/common-association/src/main/java/apelet/association/plugin/electronicJournal/ElectronicJournalFormPlugin.java @@ -1,13 +1,22 @@ package apelet.association.plugin.electronicJournal; +import apelet.association.plugin.fileLibraryMange.FileLibrayFormPlugin; import apelet.common.core.exception.MyRuntimeException; import apelet.common.core.object.ObjectValue; +import apelet.common.core.object.TokenData; import apelet.common.core.util.ApplicationContextHolder; import apelet.common.generator.utils.OrmGenDataSourceUtil; import apelet.common.online.abstractplugin.ExecutePluginParent; import apelet.common.online.model.constant.AttributeEnum; import apelet.common.orm.impl.Selector; import apelet.common.orm.impl.SelectorItem; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Date; public class ElectronicJournalFormPlugin extends ExecutePluginParent { @@ -17,21 +26,155 @@ public class ElectronicJournalFormPlugin extends ExecutePluginParent { ormGenDataSourceUtil = ApplicationContextHolder.getBean(OrmGenDataSourceUtil.class); } +// @Override +// public void formCreated(String widgetVariableName, ObjectValue objectValue) { +// super.formCreated(widgetVariableName, objectValue); +// Object viewCount = objectValue.get("view_count"); +// if (viewCount == null) { +// this.setWidgetAttribute("viewCount", AttributeEnum.VALUE_CHANGE, "0"); +// } else { +// objectValue.put("view_count", (Integer) viewCount + 1); +// Selector selector = new Selector(); +// selector.getList().add(new SelectorItem("view_count")); +// try { +// ormGenDataSourceUtil.update(objectValue.getTableName(), objectValue, selector); +// } catch (Exception e) { +// throw new MyRuntimeException(e.getMessage()); +// } +// } +// } + + /** + * 按钮触发事件:检测到"保存"按钮时,将电子期刊附件(file)同步写入文件库表 file_library + * - file 附件 JSON 数组整体存入 file_library.file_name + * - 自动解析第一个文件的大小与类型,写入 file_size / file_type + * - 阅读权限(read_auth)、阅读次数(read_count)、状态(publish_status)、分类(classification)默认 0 + * - 补齐创建人/创建时间等公共字段,其余字段保持 null + * 注意:每次点击"保存"都会新增一条文件库记录 + * + * @param widgetVariableName 按钮标识 + * @param objectValue 当前表单数据对象 + */ @Override - public void formCreated(String widgetVariableName, ObjectValue objectValue) { - super.formCreated(widgetVariableName, objectValue); - Object viewCount = objectValue.get("view_count"); - if (viewCount == null) { - this.setWidgetAttribute("viewCount", AttributeEnum.VALUE_CHANGE, "0"); - } else { - objectValue.put("view_count", (Integer) viewCount + 1); - Selector selector = new Selector(); - selector.getList().add(new SelectorItem("view_count")); - try { - ormGenDataSourceUtil.update(objectValue.getTableName(), objectValue, selector); - } catch (Exception e) { - throw new MyRuntimeException(e.getMessage()); + public void buttonTriggered(String widgetVariableName, ObjectValue objectValue) { + super.buttonTriggered(widgetVariableName, objectValue); + // 仅响应"保存"按钮 + if (!"保存".equals(widgetVariableName)) { + return; + } + saveAttachmentToFileLibrary(objectValue); + } + + /** + * 保存电子期刊附件到文件库表 file_library + * 附件为空时直接跳过,不写入任何记录 + * + * @param objectValue 电子期刊表单数据对象 + */ + private void saveAttachmentToFileLibrary(ObjectValue objectValue) { + // 读取附件字段(电子期刊表单的附件控件为 file),附件为空则跳过 + Object fileObj = objectValue.get("file"); + if (fileObj == null) { + return; + } + String fileText = fileObj.toString(); + if (fileText.isEmpty()) { + return; + } + // 解析附件 JSON 数组 + JSONArray fileArray; + try { + fileArray = JSON.parseArray(fileText); + } catch (Exception e) { + fileArray = null; + } + if (fileArray == null || fileArray.isEmpty()) { + return; + } + // file_size / file_type 为单值字段,取第一个文件的大小与类型 + String fileType = null; + String fileSize = null; + JSONObject firstFile = fileArray.getJSONObject(0); + if (firstFile != null) { + fileType = resolveFileType(firstFile.getString("filename")); + fileSize = resolveFileSize(firstFile); + } + // 当前登录用户与当前时间(公共字段) + TokenData tokenData = TokenData.takeFromRequest(); + Long userId = tokenData == null ? null : tokenData.getUserId(); + Date now = new Date(); + // 组装 file_library 记录 + ObjectValue record = new ObjectValue("file_library"); + record.put("file_name", fileText); + record.put("file_type", fileType); + record.put("file_size", fileSize); + // 阅读权限、阅读次数、状态、分类默认 0 + record.put("read_auth", "1"); + record.put("read_count", 0); + record.put("publish_status", "1"); + record.put("classification", "2"); + // 公共字段 + record.put("create_user_id", userId); + record.put("create_time", now); + record.put("update_user_id", userId); + record.put("update_time", now); + record.put("deleted_flag", 1); + // 插入文件库表,主键 id 由框架自动生成 + try { + ormGenDataSourceUtil.addNew("file_library", record); + } catch (Exception e) { + throw new MyRuntimeException("保存附件到文件库失败:" + e.getMessage()); + } + } + + /** + * 通过 HEAD 请求获取 OSS 文件大小,并格式化为 KB/MB 展示字符串 + * 获取失败返回 null,不阻塞保存流程 + * + * @param file 附件 JSON 中的单个文件对象 + * @return 格式化后的文件大小(如 "1.6 MB"),失败返回 null + */ + private String resolveFileSize(JSONObject file) { + String baseUrl = file.getString("baseUrl"); + String uploadPath = file.getString("uploadPath"); + String filename = file.getString("filename"); + if (baseUrl == null || uploadPath == null || filename == null) { + return null; + } + String fullUrl = baseUrl + "/" + uploadPath + "/" + filename; + HttpURLConnection connection = null; + try { + URL url = new URL(fullUrl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("HEAD"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + connection.connect(); + long fileSize = connection.getContentLengthLong(); + if (fileSize > 0) { + return FileLibrayFormPlugin.formatFileSize(fileSize); } + } catch (Exception e) { + // 获取大小失败时返回 null,不影响保存 + System.out.println("获取附件文件大小失败:" + fullUrl + "," + e.getMessage()); + } finally { + if (connection != null) { + connection.disconnect(); + } + } + return null; + } + + /** + * 从文件名提取扩展名作为文件类型,如 "期刊.pdf" -> "pdf" + * + * @param fileName 文件名 + * @return 文件扩展名,无法识别返回 null + */ + private String resolveFileType(String fileName) { + if (fileName == null || fileName.isEmpty() || !fileName.contains(".")) { + return null; } + return fileName.substring(fileName.lastIndexOf(".") + 1); } } diff --git a/common/common-association/src/main/java/apelet/association/plugin/fileLibraryMange/FileLibrayListPlugin.java b/common/common-association/src/main/java/apelet/association/plugin/fileLibraryMange/FileLibrayListPlugin.java index ec460a7..fa817e7 100644 --- a/common/common-association/src/main/java/apelet/association/plugin/fileLibraryMange/FileLibrayListPlugin.java +++ b/common/common-association/src/main/java/apelet/association/plugin/fileLibraryMange/FileLibrayListPlugin.java @@ -1,5 +1,6 @@ package apelet.association.plugin.fileLibraryMange; +import apelet.common.core.object.ObjectValue; import apelet.common.online.abstractplugin.ListPlugin; import apelet.common.online.dto.OnlineEventPluginExecuteDto; import apelet.common.online.dto.OnlineFilterDto; @@ -7,6 +8,8 @@ import apelet.common.orm.impl.Filter; import apelet.common.orm.impl.FilterItem; import java.util.ArrayList; +import java.util.List; +import java.util.Map; public class FileLibrayListPlugin extends ListPlugin { @Override @@ -24,4 +27,38 @@ public class FileLibrayListPlugin extends ListPlugin { } return filter; } + + /** + * 编辑按钮检测:仅允许选中文件的 classification=5(上传文件)时才可编辑 + * 否则提示并取消编辑操作 + * + * @param widgetVariableName 按钮标识 + * @param objectValue 当前事件数据对象 + */ + @Override + public void buttonTriggered(String widgetVariableName, ObjectValue objectValue) { + super.buttonTriggered(widgetVariableName, objectValue); + // 仅对"编辑"按钮做检测 + if (!"编辑".equals(widgetVariableName)) { + return; + } + // 获取列表当前选中的行数据 + List rowDatas = getDto().getModel().getRowDatas(); + if (rowDatas == null || rowDatas.isEmpty()) { + showWarningMessage("请先在列表中选中要编辑的文件"); + this.cancelOperate(); + return; + } + // 遍历选中行,任一文件 classification != 5 则禁止编辑 + for (Map rowData : rowDatas) { + Object classificationObj = rowData.get("classification"); + String classification = classificationObj == null ? "" : String.valueOf(classificationObj); + if (!"5".equals(classification)) { + showWarningMessage("仅\"上传文件\"分类的文件允许编辑"); + this.cancelOperate(); + return; + } + } + } + } diff --git a/common/common-association/src/main/java/apelet/association/plugin/quotation/QuotationPlugin.java b/common/common-association/src/main/java/apelet/association/plugin/quotation/QuotationPlugin.java index 061404d..3cb1628 100644 --- a/common/common-association/src/main/java/apelet/association/plugin/quotation/QuotationPlugin.java +++ b/common/common-association/src/main/java/apelet/association/plugin/quotation/QuotationPlugin.java @@ -1,5 +1,7 @@ package apelet.association.plugin.quotation; +import apelet.association.plugin.fileLibraryMange.FileLibrayFormPlugin; +import apelet.common.core.exception.MyRuntimeException; import apelet.common.core.object.ObjectCollection; import apelet.common.core.object.ObjectValue; import apelet.common.core.object.TokenData; @@ -7,9 +9,15 @@ import apelet.common.core.util.ApplicationContextHolder; import apelet.common.generator.utils.OrmGenDataSourceUtil; import apelet.common.online.abstractplugin.ExecutePluginParent; import apelet.common.online.model.constant.AttributeEnum; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; import liquibase.repackaged.org.apache.commons.lang3.StringUtils; import java.math.BigDecimal; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -92,4 +100,127 @@ public class QuotationPlugin extends ExecutePluginParent { type = StringUtils.removeEnd(type, ","); this.setWidgetAttribute("type", AttributeEnum.VALUE_CHANGE, type); } + + @Override + public void buttonTriggered(String widgetVariableName, ObjectValue objectValue) { + super.buttonTriggered(widgetVariableName, objectValue); + // 仅响应"保存"按钮 + if (!"保存".equals(widgetVariableName)) { + return; + } + saveAttachmentToFileLibrary(objectValue); + } + + /** + * 保存报价单附件到文件库表 file_library + * 附件为空时直接跳过,不写入任何记录 + * + * @param objectValue 报价单表单数据对象 + */ + private void saveAttachmentToFileLibrary(ObjectValue objectValue) { + // 读取附件字段,附件为空则跳过 + Object fileTextObj = objectValue.get("file_text"); + if (fileTextObj == null) { + return; + } + String fileText = fileTextObj.toString(); + if (fileText.isEmpty()) { + return; + } + // 解析附件 JSON 数组 + JSONArray fileArray; + try { + fileArray = JSON.parseArray(fileText); + } catch (Exception e) { + fileArray = null; + } + if (fileArray == null || fileArray.isEmpty()) { + return; + } + // file_size / file_type 为单值字段,取第一个文件的大小与类型 + String fileType = null; + String fileSize = null; + JSONObject firstFile = fileArray.getJSONObject(0); + if (firstFile != null) { + fileType = resolveFileType(firstFile.getString("filename")); + fileSize = resolveFileSize(firstFile); + } + // 当前登录用户与当前时间(公共字段) + TokenData tokenData = TokenData.takeFromRequest(); + Long userId = tokenData == null ? null : tokenData.getUserId(); + Date now = new Date(); + // 组装 file_library 记录 + ObjectValue record = new ObjectValue("file_library"); + record.put("file_name", fileText); + record.put("file_type", fileType); + record.put("file_size", fileSize); + // 阅读权限、阅读次数、状态、分类默认 0 + record.put("read_auth", "1"); + record.put("read_count", 0); + record.put("publish_status", "1"); + record.put("classification", "3"); + // 公共字段 + record.put("create_user_id", userId); + record.put("create_time", now); + record.put("update_user_id", userId); + record.put("update_time", now); + record.put("deleted_flag", 1); + // 插入文件库表,主键 id 由框架自动生成 + try { + ormGenDataSourceUtil.addNew("file_library", record); + } catch (Exception e) { + throw new MyRuntimeException("保存附件到文件库失败:" + e.getMessage()); + } + } + + /** + * 通过 HEAD 请求获取 OSS 文件大小,并格式化为 KB/MB 展示字符串 + * 获取失败返回 null,不阻塞保存流程 + * + * @param file 附件 JSON 中的单个文件对象 + * @return 格式化后的文件大小(如 "1.6 MB"),失败返回 null + */ + private String resolveFileSize(JSONObject file) { + String baseUrl = file.getString("baseUrl"); + String uploadPath = file.getString("uploadPath"); + String filename = file.getString("filename"); + if (baseUrl == null || uploadPath == null || filename == null) { + return null; + } + String fullUrl = baseUrl + "/" + uploadPath + "/" + filename; + HttpURLConnection connection = null; + try { + URL url = new URL(fullUrl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("HEAD"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + connection.connect(); + long fileSize = connection.getContentLengthLong(); + if (fileSize > 0) { + return FileLibrayFormPlugin.formatFileSize(fileSize); + } + } catch (Exception e) { + // 获取大小失败时返回 null,不影响保存 + System.out.println("获取附件文件大小失败:" + fullUrl + "," + e.getMessage()); + } finally { + if (connection != null) { + connection.disconnect(); + } + } + return null; + } + + /** + * 从文件名提取扩展名作为文件类型,如 "合同.pdf" -> "pdf" + * + * @param fileName 文件名 + * @return 文件扩展名,无法识别返回 null + */ + private String resolveFileType(String fileName) { + if (StringUtils.isEmpty(fileName) || !fileName.contains(".")) { + return null; + } + return fileName.substring(fileName.lastIndexOf(".") + 1); + } }