氚云低代码平台列表中增加批量下载附件功能

2025-05-10 15:08:55 世界杯经典歌曲

功能需要前后端代码实现:

主要是选中数据,然后再查询附件表获取到附件ID进行下载

最终效果:

使用前需要先在列表中增加按钮

[通用]附件批量下载

可用位置:✔表单 / ✔列表

//此函数是在表单/列表前端调用

$.IDownloadAttachments( ["附件Id_1", "附件Id_2" ] );

[系统-附件/图片记录表] H_BizObjectFile

数据库表名:H_BizObjectFile

序号字段编码字段释义备注1ObjectId附件/图片Id主键,附件/图片的唯一标识2LastVersion版本3SchemaCode附件/图片所在主表的表单编码4ChildSchemaCode如附件/图片控件在子表中,则有子表控件编码5PropertyName所在表单的附件/图片控件编码,若是子表中的附件/图片,则是子表内控件编码6BizObjectId所在表单数据Id,若是子表中的附件/图片,则是子表数据Id

列表中的后端代码:

using System;

using System.Collections.Generic;

using System.Text;

using H3;

public class D285663saqvtcdb2zei2avt80fgg_ListViewController: H3.SmartForm.ListViewController

{

public D285663saqvtcdb2zei2avt80fgg_ListViewController(H3.SmartForm.ListViewRequest request): base(request)

{

}

protected override void OnLoad(H3.SmartForm.LoadListViewResponse response)

{

base.OnLoad(response);

// 添加自定义按钮“plxz”(批量下载)

// 检查是否已经存在 "plxz" 按钮,避免重复添加

if(!response.Actions.ContainsKey("plxz"))

{

// 【需修改】动作名称 "plxz" 和显示名称 "批量下载" 可根据新表单调整,例如 "batchDownload" 和 "Download All"

response.Actions.Add("plxz", new H3.SmartForm.ViewAction("plxz", "批量下载", "icon-download"));

}

}

protected override void OnSubmit(string actionName, H3.SmartForm.ListViewPostValue postValue, H3.SmartForm.SubmitListViewResponse response)

{

//响应后端下载88

try

{

// 调用基类方法,确保 H3 平台的默认逻辑执行

base.OnSubmit(actionName, postValue, response);

// 判断是否为“批量下载”动作

if(actionName == "plxz")

{

// 【需修改】动作名称 "plxz" 需与前端 $.ListView.Post 的 actionName 一致,例如 "batchDownload"

// 调试:打印前端传入的数据,便于排查问题

if(postValue.Data != null)

{

System.Diagnostics.Debug.WriteLine("postValue.Data Keys:");

foreach(string key in postValue.Data.Keys)

{

object value = postValue.Data[key];

string valueStr = value != null ? value.ToString() : "null";

System.Diagnostics.Debug.WriteLine("Key: " + key + ", Value: " + valueStr);

}

}

else

{

System.Diagnostics.Debug.WriteLine("postValue.Data is null");

response.Errors.Add("后端未收到任何数据!");

return;

}

// 定义变量:存储选中数据的 ID 字符串和对象

string selectedObjectIdsStr = null;

object selectedObjectIdsObj = null;

// 定义键名,用于从 postValue.Data 中提取数据

string keyUsed = "ObjectIds";

// 【需修改】键名 "ObjectIds" 需与前端 $.ListView.Post 的键名一致,若改为 "SelectedIds",需同步调整

// 检查前端是否传入了指定键名的数据

if(postValue.Data.ContainsKey(keyUsed))

{

selectedObjectIdsObj = postValue.Data[keyUsed];

System.Diagnostics.Debug.WriteLine("Raw ObjectIds Object: " + (selectedObjectIdsObj != null ? selectedObjectIdsObj.ToString() : "null"));

}

else

{

// 如果键名不存在,输出所有可用键名并返回错误

string possibleKeys = string.Join(", ", postValue.Data.Keys);

System.Diagnostics.Debug.WriteLine("Possible Keys in postValue.Data: " + possibleKeys);

response.Errors.Add("后端未收到ObjectIds,可能键名不匹配,可用键名:" + possibleKeys);

return;

}

// 处理前端传入的选中数据(可能是字符串或数组)

if(selectedObjectIdsObj != null)

{

string rawValue = selectedObjectIdsObj.ToString();

System.Diagnostics.Debug.WriteLine("Raw ToString Value: " + rawValue);

// 判断数据类型:数组或单个值

if(rawValue == "System.String[]" || rawValue == "System.Object[]")

{

List < string > idList = new List();

if(selectedObjectIdsObj is Array)

{

// 如果是数组,遍历并提取每个 ID

foreach(object item in (Array)selectedObjectIdsObj)

{

if(item != null)

{

idList.Add(item.ToString());

}

}

}

else

{

// 如果是单值,直接添加

idList.Add(rawValue);

}

// 将 ID 列表转换为逗号分隔的字符串

selectedObjectIdsStr = string.Join(",", idList);

System.Diagnostics.Debug.WriteLine("Converted array to selectedObjectIdsStr: " + selectedObjectIdsStr);

}

else

{

// 如果不是数组,直接使用原始值

selectedObjectIdsStr = rawValue;

System.Diagnostics.Debug.WriteLine("Assigned selectedObjectIdsStr from raw value: " + selectedObjectIdsStr);

}

}

else

{

System.Diagnostics.Debug.WriteLine("selectedObjectIdsObj is null");

response.Errors.Add(keyUsed + " 数据为空!");

return;

}

// 检查是否选择了数据

if(string.IsNullOrEmpty(selectedObjectIdsStr))

{

response.Errors.Add("请至少选择一条数据!(" + keyUsed + " 为空)");

return;

}

// 将选中数据的 ID 拆分为数组

string[] selectedObjectIds = selectedObjectIdsStr.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries);

System.Diagnostics.Debug.WriteLine("SelectedObjectIds Count: " + selectedObjectIds.Length);

System.Diagnostics.Debug.WriteLine("SelectedObjectIds Values: " + string.Join(", ", selectedObjectIds));

// 定义列表:存储所有附件 ID

List < string > attachmentIds = new List();

// 查询系统附件表 H_BizObjectFile 获取附件 ID

// 表名 "H_BizObjectFile" 为 H3 系统固定表,无需修改

// PropertyName "F0000047" 为当前表单的附件字段编码

// 【需修改】若迁移到其他表单,需将 "F0000047" 改为新表单的附件字段编码(在 H3 设计器中查看)

string sql = "SELECT ObjectId FROM H_BizObjectFile WHERE BizObjectId IN ({0}) AND PropertyName = 'F0000047'";

// 生成 IN 子句,包含所有选中数据的 ObjectId

string inClause = "'" + string.Join("','", selectedObjectIds) + "'";

sql = string.Format(sql, inClause);

System.Diagnostics.Debug.WriteLine("Generated SQL: " + sql);

try

{

// 执行 SQL 查询,获取附件记录

System.Data.DataTable dt = this.Engine.Query.QueryTable(sql, null);

if(dt != null && dt.Rows.Count > 0)

{

System.Diagnostics.Debug.WriteLine("Found " + dt.Rows.Count + " records in H_BizObjectFile");

foreach(System.Data.DataRow row in dt.Rows)

{

// 从查询结果中提取附件 ID(H_BizObjectFile 的 ObjectId 字段)

string fileId = row["ObjectId"] + "";

if(!string.IsNullOrEmpty(fileId))

{

attachmentIds.Add(fileId);

System.Diagnostics.Debug.WriteLine("Added FileId: " + fileId);

}

}

}

else

{

System.Diagnostics.Debug.WriteLine("No records found in H_BizObjectFile for selected ObjectIds");

}

}

catch(Exception ex)

{

// 捕获 SQL 查询异常

System.Diagnostics.Debug.WriteLine("SQL Query Error: " + ex.Message + "\nStackTrace: " + ex.StackTrace);

response.Errors.Add("查询附件数据失败:" + ex.Message);

return;

}

// 输出最终的附件 ID 数量

System.Diagnostics.Debug.WriteLine("Total AttachmentIds Count: " + attachmentIds.Count);

if(attachmentIds.Count > 0)

{

// 如果有附件 ID,初始化返回数据并添加结果

if(response.ReturnData == null)

{

response.ReturnData = new Dictionary();

System.Diagnostics.Debug.WriteLine("Initialized response.ReturnData");

}

// 将附件 ID 以分号分隔的字符串返回给前端

response.ReturnData.Add("attachmentIds", string.Join(";", attachmentIds));

System.Diagnostics.Debug.WriteLine("AttachmentIds Returned: " + string.Join(";", attachmentIds));

}

else

{

// 如果没有附件,提示用户

response.Errors.Add("所选数据中没有可下载的附件!");

System.Diagnostics.Debug.WriteLine("No attachments found for any selected ObjectIds");

}

}

}

catch(Exception ex)

{

// 捕获整个方法的异常

response.Errors.Add("后端处理失败:" + ex.Message);

System.Diagnostics.Debug.WriteLine("OnSubmit Error: " + ex.Message + "\nStackTrace: " + ex.StackTrace);

}

//响应后端下载88

// base.OnSubmit(actionName, postValue, response);

}

}

前端代码:

/*

* $.ListView.GetSelected()获取选中的记录

* $.ListView.RefreshView()刷新列表

* $.ListView.Post()请求后台

* $.ListView.InitQueryItems()修改过滤条件

* $.ListView.RefreshView()刷新页面

* $.ListView.ActionPreDo() 按钮执行之前的事件

*/

// 列表视图操作前置函数,用于处理批量下载动作

$.ListView.ActionPreDo = function (actionName) {

// 判断是否为“批量下载”动作,actionName 需要与后端一致

if (actionName === "plxz") { // 【需修改】根据新表单的动作名称调整,例如 "batchDownload"

// 获取用户选中的数据行

var selectedDatas = $.ListView.GetSelected();

if (!selectedDatas || selectedDatas.length === 0) {

$.IShowWarn("请选择至少一条数据!");

return;

}

// 从选中数据中提取 ObjectId,假设每行数据都有 ObjectId 字段

var selectedObjectIds = selectedDatas.map(function (data) {

return data.ObjectId; // 【需确认】确保新表单的数据结构中包含 ObjectId 字段,若字段名不同需调整

});

// 添加调试日志,输出选中的 ObjectId 数组

console.log("ObjectIds Array: " + JSON.stringify(selectedObjectIds));

// 调用后端接口,发送批量下载请求

$.ListView.Post(

"plxz", // 【需修改】动作名称需与后端 OnSubmit 中的 actionName 一致,例如 "batchDownload"

{ "ObjectIds": selectedObjectIds }, // 前端传入 ObjectIds 数组,后端需适配此键名

function (response) {

// 处理后端成功响应

if (response.ReturnData && response.ReturnData.attachmentIds) {

var attachmentIds = response.ReturnData.attachmentIds.split(";");

console.log("AttachmentIds: " + attachmentIds);

// 调用 H3 内置方法下载附件

$.IDownloadAttachments(attachmentIds);

$.IShowSuccess("成功", "附件下载已触发!");

} else if (response.Errors && response.Errors.length > 0) {

$.IShowError("错误", response.Errors.join("\n"));

} else {

$.IShowError("错误", "未找到可下载的附件!");

}

},

function (error) {

// 处理请求失败

$.IShowError("错误", "请求失败:" + error);

},

true // 异步请求

);

}

};