1 changed files with 168 additions and 0 deletions
@ -0,0 +1,168 @@ |
|||||||
|
package apelet.association.plugin.active; |
||||||
|
|
||||||
|
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 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; |
||||||
|
|
||||||
|
/** |
||||||
|
* 活动直播文件归档插件 |
||||||
|
* 监听 association_activity 表单的"保存"按钮, |
||||||
|
* 将活动直播视频文件(video 字段)归档到文件库表 file_library: |
||||||
|
* - video 附件 JSON 数组整体存入 file_library.file_name |
||||||
|
* - 自动解析第一个文件的大小与类型,写入 file_size / file_type |
||||||
|
* - 归档默认值:分类(classification)4、阅读权限(read_auth)1、 |
||||||
|
* 阅读次数(read_count)0、发布状态(publish_status)1 |
||||||
|
* - 补齐创建人/创建时间等公共字段,其余字段保持 null |
||||||
|
* 注意:每次点击"保存"都会新增一条文件库记录 |
||||||
|
*/ |
||||||
|
public class ActivityLiveArchivePlugin extends ExecutePluginParent { |
||||||
|
|
||||||
|
/** 文件库目标表 */ |
||||||
|
private static final String FILE_LIBRARY_TABLE = "file_library"; |
||||||
|
|
||||||
|
private final OrmGenDataSourceUtil ormGenDataSourceUtil; |
||||||
|
|
||||||
|
public ActivityLiveArchivePlugin() { |
||||||
|
ormGenDataSourceUtil = ApplicationContextHolder.getBean(OrmGenDataSourceUtil.class); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 按钮触发事件:检测到"保存"按钮时,将活动直播视频归档到文件库 |
||||||
|
* |
||||||
|
* @param widgetVariableName 按钮标识 |
||||||
|
* @param objectValue 当前表单数据对象 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void buttonTriggered(String widgetVariableName, ObjectValue objectValue) { |
||||||
|
super.buttonTriggered(widgetVariableName, objectValue); |
||||||
|
// 仅响应"保存"按钮
|
||||||
|
if (!"保存".equals(widgetVariableName)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
saveLiveVideoToFileLibrary(objectValue); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 保存活动直播视频到文件库表 file_library |
||||||
|
* 视频字段为空时直接跳过,不写入任何记录 |
||||||
|
* |
||||||
|
* @param objectValue 活动表单数据对象 |
||||||
|
*/ |
||||||
|
private void saveLiveVideoToFileLibrary(ObjectValue objectValue) { |
||||||
|
// 读取活动直播视频字段(association_activity.video),为空则跳过
|
||||||
|
Object videoObj = objectValue.get("video"); |
||||||
|
if (videoObj == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
String videoText = videoObj.toString(); |
||||||
|
if (videoText.isEmpty()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
// 解析附件 JSON 数组
|
||||||
|
JSONArray fileArray; |
||||||
|
try { |
||||||
|
fileArray = JSON.parseArray(videoText); |
||||||
|
} 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_TABLE); |
||||||
|
record.put("file_name", videoText); |
||||||
|
record.put("file_type", fileType); |
||||||
|
record.put("file_size", fileSize); |
||||||
|
// 活动直播归档默认值:分类 4、阅读权限 1、阅读次数 0、发布状态 1
|
||||||
|
record.put("classification", "4"); |
||||||
|
record.put("read_auth", "1"); |
||||||
|
record.put("read_count", 0); |
||||||
|
record.put("publish_status", "1"); |
||||||
|
// 公共字段
|
||||||
|
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_TABLE, 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; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 从文件名提取扩展名作为文件类型,如 "直播回放.mp4" -> "mp4" |
||||||
|
* |
||||||
|
* @param fileName 文件名 |
||||||
|
* @return 文件扩展名,无法识别返回 null |
||||||
|
*/ |
||||||
|
private String resolveFileType(String fileName) { |
||||||
|
if (fileName == null || fileName.isEmpty() || !fileName.contains(".")) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return fileName.substring(fileName.lastIndexOf(".") + 1); |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue