功能需要前后端代码实现:
主要是选中数据,然后再查询附件表获取到附件ID进行下载
最终效果:
使用前需要先在列表中增加按钮
[通用]附件批量下载
可用位置:✔表单 / ✔列表
//此函数是在表单/列表前端调用
$.IDownloadAttachments( ["附件Id_1", "附件Id_2" ] );
[系统-附件/图片记录表] H_BizObjectFile
数据库表名:H_BizObjectFile
序号 | 字段编码 | 字段释义 | 备注 |
---|---|---|---|
1 | ObjectId | 附件/图片Id | 主键,附件/图片的唯一标识 |
2 | LastVersion | 版本 | |
3 | SchemaCode | 附件/图片所在主表的表单编码 | |
4 | ChildSchemaCode | 如附件/图片控件在子表中,则有子表控件编码 | |
5 | PropertyName | 所在表单的附件/图片控件编码,若是子表中的附件/图片,则是子表内控件编码 | |
6 | BizObjectId | 所在表单数据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<string>();
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<string>();
// 查询系统附件表 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<string, object>();
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 // 异步请求
);
}
};