diff --git a/AndroidPDACommand.csproj b/AndroidPDACommand.csproj
index c53bcc5bfb2073978df335ea5e15b51b1d7bb8c1..13b436e60b5038393f72f9fbb676989ddfefa3e8 100644
--- a/AndroidPDACommand.csproj
+++ b/AndroidPDACommand.csproj
@@ -1,76 +1,38 @@
-
-
-
+
- Debug
- AnyCPU
- {8414FB54-B60D-4F9A-9505-B5E0B2D86C43}
+ net8.0-windows
Library
- Properties
AndroidPDACommand
AndroidPDACommand
- v4.7.2
- 512
SAK
SAK
SAK
SAK
-
true
+ true
+ true
+ true
+ false
+ false
+ false
+ false
+ bin\
true
full
false
- bin\
DEBUG;TRACE
prompt
4
- MinimumRecommendedRules.ruleset
pdbonly
true
- bin\
TRACE
prompt
4
-
-
- false
-
-
- D:\ForguncyOtherVersion\8.0.6.0\Website\designerBin\Forguncy.Commands.dll
-
-
- D:\ForguncyOtherVersion\8.0.6.0\Website\designerBin\Forguncy.Commands.Design.dll
-
-
- D:\ForguncyOtherVersion\8.0.6.0\Website\designerBin\GrapeCity.Forguncy.Plugin.dll
-
-
- False
- D:\ForguncyOtherVersion\8.0.6.0\Website\bin\GrapeCity.Forguncy.ServerApi.dll
-
-
- packages\Jiguang.JPush.1.2.5\lib\net45\Jiguang.JPush.dll
-
-
- packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -119,6 +81,7 @@
+
@@ -143,77 +106,70 @@
-
+
+
+
+
+ E:\forAgentA\forguncy\Forguncy.Server2\designerBin\Forguncy.Commands.dll
+ False
+
+
+ E:\forAgentA\forguncy\Forguncy.Server2\designerBin\Forguncy.Commands.Design.dll
+ False
+
+
+ E:\forAgentA\forguncy\Forguncy.Server2\designerBin\GrapeCity.Forguncy.Plugin.dll
+ False
+
+
+ E:\forAgentA\forguncy\Forguncy.Server2\bin\GrapeCity.Forguncy.ServerApi.dll
+ False
+
+
+
+
+
-
+
PreserveNewest
-
-
-
+
PreserveNewest
-
-
+
Always
-
-
-
+
PreserveNewest
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
- "D:\ForguncyCode\puglin\PluginTools\PluginPackageTool\bin\Release\PluginPackageTool.exe" "$(ProjectDir)\" "$(ConfigurationName)"
-
-
\ No newline at end of file
+
+
+
+
diff --git a/Device_Info_Json.cs b/Device_Info_Json.cs
new file mode 100644
index 0000000000000000000000000000000000000000..2c3c05a21f737c6dcbbd5e400adc1895889ab671
--- /dev/null
+++ b/Device_Info_Json.cs
@@ -0,0 +1,27 @@
+using GrapeCity.Forguncy.Commands;
+using GrapeCity.Forguncy.Plugin;
+using System.ComponentModel;
+
+namespace AndroidPDACommand
+{
+ [Icon("pack://application:,,,/AndroidPDACommand;component/Resources/Icon_Phone.png")]
+ [Category("活字格安卓容器(HAC)")]
+ [OrderWeight(903)]
+ public class Device_Info_Json : BaseCommand
+ {
+ [DisplayName("将设备信息JSON返回到变量")]
+ [Description("读取设备唯一标识、品牌、型号、Android版本、APP版本、WebView版本等基础信息。")]
+ [SearchableProperty]
+ [ResultToProperty]
+ public string DeviceInfoJson { get; set; }
+
+ public override string ToString()
+ {
+ if (string.IsNullOrEmpty(DeviceInfoJson))
+ {
+ return "读取设备信息";
+ }
+ return "读取设备信息:" + DeviceInfoJson;
+ }
+ }
+}
diff --git a/JPushServerCommand.cs b/JPushServerCommand.cs
index 317c421e4e5fcecbd923cda3079c40bddbd97a5b..c6ff1b64f1e62cb1d9dc9a7742601d86c755cdc8 100644
--- a/JPushServerCommand.cs
+++ b/JPushServerCommand.cs
@@ -12,7 +12,6 @@ using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Markup;
-using System.Xml.Serialization.Configuration;
namespace AndroidPDACommand
{
@@ -66,7 +65,7 @@ namespace AndroidPDACommand
if (!string.IsNullOrEmpty(url))
{
- intentObj.Add("url", "intent:#Intent;action=com.huozige.lab.container.navigate;component=com.huozige.lab.container/com.huozige.lab.container.MainActivity;S.url=" + System.Web.HttpUtility.UrlEncode(url) + ";end");
+ intentObj.Add("url", "intent:#Intent;action=com.huozige.lab.container.navigate;component=com.huozige.lab.container/com.huozige.lab.container.MainActivity;S.url=" + WebUtility.UrlEncode(url) + ";end");
}
else
{
diff --git a/OfflinePlusAddPattern_Async.cs b/OfflinePlusAddPattern_Async.cs
index dfbe5913fb1ddf00a20da89e1abd74cb7179d63a..308192dbd7b8fb86d8fdb496091571f974134099 100644
--- a/OfflinePlusAddPattern_Async.cs
+++ b/OfflinePlusAddPattern_Async.cs
@@ -1,10 +1,14 @@
using System.Collections.Generic;
using System.ComponentModel;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
using GrapeCity.Forguncy.Commands;
using GrapeCity.Forguncy.Plugin;
namespace AndroidPDACommand
{
+ [Icon("pack://application:,,,/AndroidPDACommand;component/Resources/Icon_OfflineDownload.png")]
+ [Category("活字格安卓容器(HAC)")]
public class OfflinePlusAddPattern_Async : BaseAsyncCommand
{
[FormulaProperty]
@@ -20,27 +24,109 @@ namespace AndroidPDACommand
[FormulaProperty]
public object Description { get; set; }
- [DisplayName("表单项")]
- [ObjectListProperty(ItemType = typeof(OfflineFormItem))]
- public List FormItems { get; set; }
+ [Required]
+ [FormulaProperty]
+ [DisplayName("版本号")]
+ [Description("同一项目编号下的表单定义版本,用于区分表单结构变更。")]
+ public string SchemaVersion { get; set; } = "1.0";
+
+ [FormulaProperty]
+ [DisplayName("手册附件单元格")]
+ [Description("选择保存 PDF 手册附件的单元格。下载离线表单时会把 PDF 手册随表单一起保存到离线设备。")]
+ public object ManualAttachmentCell { get; set; }
+
+ [FormulaProperty]
+ [DisplayName("员工签名单元格")]
+ [Description("选择保存员工签名附件的单元格。下载离线表单时会把签名文件随表单一起保存到离线设备。")]
+ public object SignatureAttachmentCell { get; set; }
+
+ [DisplayName("步骤")]
+ [ObjectListProperty(ItemType = typeof(OfflineFormStep))]
+ public List Steps { get; set; }
public override string ToString()
{
- return "添加项目";
+ return "下载离线表单";
}
}
- public class OfflineFormItem : ObjectPropertyBase, INamedObject
+ public class OfflineFormStep : ObjectPropertyBase, INamedObject
{
public string Name { get; set; }
+ [FormulaProperty]
+ [DisplayName("步骤编号")]
+ [Description("该步骤的唯一标识,同一个离线表单项目内必须唯一。")]
+ public object StepId { get; set; }
+
+ [FormulaProperty]
+ [DisplayName("标题")]
+ public object Title { get; set; }
+
+ [TreeProperty(NodeType = typeof(OfflineFormNode), DefaultNodeName = "节点")]
+ [DisplayName("页面内容")]
+ public List Items { get; set; } = new List();
+ }
+
+ public class OfflineFormNode : ObjectPropertyBase, ITreeNode
+ {
+ private static readonly string[] CommonFieldVisibleProperties =
+ {
+ nameof(ItemId),
+ nameof(ItemType),
+ nameof(Title),
+ nameof(Hint),
+ nameof(Required)
+ };
+
+ private static readonly HashSet FieldTypeControlledProperties = new HashSet(CommonFieldVisibleProperties)
+ {
+ nameof(Value),
+ nameof(CheckOptions),
+ nameof(SelectOptionsList),
+ nameof(IncludeSeconds),
+ nameof(MaxCount),
+ nameof(AllowImageUpload),
+ nameof(CompressionOptions),
+ nameof(WatermarkOptions),
+ nameof(FileItemConfig)
+ };
+
+ private static readonly Dictionary> FieldVisiblePropertiesByType = new Dictionary>
+ {
+ { "textItem", CreateFieldVisibleProperties(nameof(Value), nameof(CheckOptions)) },
+ { "passwordItem", CreateFieldVisibleProperties(nameof(Value), nameof(CheckOptions)) },
+ { "selectItem", CreateFieldVisibleProperties(nameof(Value), nameof(SelectOptionsList)) },
+ { "datePicker", CreateFieldVisibleProperties(nameof(Value)) },
+ { "timePicker", CreateFieldVisibleProperties(nameof(Value), nameof(IncludeSeconds)) },
+ { "imageItem", CreateFieldVisibleProperties(nameof(MaxCount), nameof(AllowImageUpload), nameof(CompressionOptions), nameof(WatermarkOptions)) },
+ { "fileItem", CreateFieldVisibleProperties(nameof(FileItemConfig)) }
+ };
+
+ [DisplayName("节点名称")]
+ public string Text { get; set; }
+
+ [Browsable(false)]
+ public IEnumerable Children { get; set; } = new List();
+
+ [DisplayName("节点类型")]
+ [ComboProperty(ValueList = "group|text|field", DisplayList = "分组|普通文本|表单项")]
+ public string NodeType { get; set; } = "group";
+
+ [FormulaProperty]
+ [DisplayName("说明内容")]
+ public object Content { get; set; }
+
+ [DisplayName("默认折叠")]
+ public bool DefaultCollapsed { get; set; }
+
[FormulaProperty]
[DisplayName("编号")]
[Description("该表单项的唯一标识,全局唯一,无论是同一项目内,还是跨项目,都必须唯一,更建议使用项目编号作为前缀拼接;例如项目为Project01,则该表单项编号为Project01_Name")]
public object ItemId { get; set; }
[DisplayName("类型")]
- [ComboProperty(ValueList = "textItem|passwordItem|selectItem", DisplayList = "文本框|密码框|选择框")]
+ [ComboProperty(ValueList = "textItem|passwordItem|selectItem|datePicker|timePicker|imageItem|fileItem", DisplayList = "文本框|密码框|选择框|日期选择|时间选择|图片列表|文件上传")]
public string ItemType { get; set; } = "textItem";
[FormulaProperty]
@@ -57,6 +143,10 @@ namespace AndroidPDACommand
[FormulaProperty]
[DisplayName("默认值")]
public object Value { get; set; }
+
+ [DisplayName("包含秒")]
+ [Description("仅时间选择类型生效。启用后可选择时分秒;关闭时使用系统原生时分选择器。")]
+ public bool IncludeSeconds { get; set; }
[ObjectProperty(ObjType = typeof(CheckOptions))]
@@ -67,18 +157,92 @@ namespace AndroidPDACommand
[DisplayName("选则项")]
public List SelectOptionsList { get; set; }
+ [FormulaProperty]
+ [DisplayName("图片最大数量")]
+ public object MaxCount { get; set; } = 9;
+
+ [DisplayName("允许图片上传")]
+ [Description("仅图片列表类型生效。启用后填报时除拍照外还可以从本地选择图片。")]
+ public bool AllowImageUpload { get; set; }
+
+ [ObjectProperty(ObjType = typeof(ImageCompressionOptions))]
+ [DisplayName("图片压缩设置")]
+ public ImageCompressionOptions CompressionOptions { get; set; } = new ImageCompressionOptions();
+
+ [ObjectProperty(ObjType = typeof(ImageWatermarkOptions))]
+ [DisplayName("拍照水印配置")]
+ public ImageWatermarkOptions WatermarkOptions { get; set; } = new ImageWatermarkOptions();
+
+ [ObjectProperty(ObjType = typeof(FileItemConfig))]
+ [DisplayName("文件上传配置")]
+ public FileItemConfig FileItemConfig { get; set; } = new FileItemConfig();
+
public override bool GetDesignerPropertyVisible(string propertyName)
{
+ var isField = NodeType == "field";
+ var isText = NodeType == "text";
+ var isGroup = NodeType == "group";
+
switch (propertyName)
{
- case nameof(SelectOptionsList):
- return ItemType == "selectItem";
- case nameof(CheckOptions):
- return ItemType == "textItem" || ItemType == "passwordItem";
+ case nameof(Content):
+ return isText;
+ case nameof(DefaultCollapsed):
+ return isGroup;
default:
+ if (isField && FieldTypeControlledProperties.Contains(propertyName))
+ {
+ return IsFieldPropertyVisible(ItemType, propertyName);
+ }
return base.GetDesignerPropertyVisible(propertyName);
}
}
+
+ public override object Clone()
+ {
+ return new OfflineFormNode
+ {
+ Text = Text,
+ Children = Children == null ? new List() : Children.ToList(),
+ NodeType = NodeType,
+ Content = Content,
+ DefaultCollapsed = DefaultCollapsed,
+ ItemId = ItemId,
+ ItemType = ItemType,
+ Title = Title,
+ Hint = Hint,
+ Required = Required,
+ Value = Value,
+ IncludeSeconds = IncludeSeconds,
+ CheckOptions = CheckOptions,
+ SelectOptionsList = SelectOptionsList,
+ MaxCount = MaxCount,
+ AllowImageUpload = AllowImageUpload,
+ CompressionOptions = CompressionOptions,
+ WatermarkOptions = WatermarkOptions,
+ FileItemConfig = FileItemConfig
+ };
+ }
+
+ private static HashSet CreateFieldVisibleProperties(params string[] propertyNames)
+ {
+ var visibleProperties = new HashSet(CommonFieldVisibleProperties);
+ foreach (var propertyName in propertyNames)
+ {
+ visibleProperties.Add(propertyName);
+ }
+ return visibleProperties;
+ }
+
+ private static bool IsFieldPropertyVisible(string itemType, string propertyName)
+ {
+ HashSet visibleProperties;
+ if (!FieldVisiblePropertiesByType.TryGetValue(itemType ?? "textItem", out visibleProperties))
+ {
+ visibleProperties = FieldVisiblePropertiesByType["textItem"];
+ }
+ return visibleProperties.Contains(propertyName);
+ }
}
public class CheckOptions : ObjectPropertyBase
@@ -106,4 +270,68 @@ namespace AndroidPDACommand
[DisplayName("显示文本")]
public object Label { get; set; }
}
-}
\ No newline at end of file
+
+ public class ImageCompressionOptions : ObjectPropertyBase
+ {
+ [DisplayName("启用压缩")]
+ [Description("默认关闭,关闭时按原图保存。启用后才使用下面的压缩参数。")]
+ public bool EnableCompression { get; set; }
+
+ [FormulaProperty]
+ [DisplayName("最长边像素")]
+ public object MaxLongEdge { get; set; } = 1600;
+
+ [FormulaProperty]
+ [DisplayName("JPEG质量")]
+ public object JpegQuality { get; set; } = 80;
+
+ [FormulaProperty]
+ [DisplayName("目标大小KB")]
+ [Description("0表示不按文件大小继续压缩。")]
+ public object MaxFileSizeKb { get; set; } = 0;
+
+ [FormulaProperty]
+ [DisplayName("最低JPEG质量")]
+ public object MinQuality { get; set; } = 60;
+ }
+
+ public class ImageWatermarkOptions : ObjectPropertyBase
+ {
+ [DisplayName("时间戳水印")]
+ public bool EnableTimestamp { get; set; } = false;
+
+ [ListProperty]
+ [DisplayName("自定义字段")]
+ public List Fields { get; set; } = new List
+ {
+ };
+ }
+
+ public class ImageWatermarkField : ObjectPropertyBase
+ {
+ [DisplayName("Key")]
+ public string Key { get; set; }
+
+ [FormulaProperty]
+ [DisplayName("Value")]
+ public object Value { get; set; }
+ }
+
+ public class FileItemConfig : ObjectPropertyBase
+ {
+ [FormulaProperty]
+ [DisplayName("最大数量")]
+ [Description("0表示不限制上传文件数量。")]
+ public object MaxCount { get; set; } = 0;
+
+ [FormulaProperty]
+ [DisplayName("允许扩展名")]
+ [Description("逗号分隔,每个扩展名前带点;留空表示不限制,例如:.pdf,.doc,.docx。")]
+ public object AllowedExtensions { get; set; }
+
+ [FormulaProperty]
+ [DisplayName("单文件最大大小KB")]
+ [Description("0表示不限制单文件大小。")]
+ public object MaxFileSizeKb { get; set; } = 0;
+ }
+}
diff --git a/OfflinePlusGetPatterns_Async.cs b/OfflinePlusGetPatterns_Async.cs
index b3257defc22bc7f19f87b08ea42e1108a1674535..6b82b0c3c9559e2e2bcf9259824ac23071f87d4c 100644
--- a/OfflinePlusGetPatterns_Async.cs
+++ b/OfflinePlusGetPatterns_Async.cs
@@ -1,18 +1,102 @@
using System.ComponentModel;
+using System;
using GrapeCity.Forguncy.Commands;
+using GrapeCity.Forguncy.Plugin;
namespace AndroidPDACommand
{
+ [Icon("pack://application:,,,/AndroidPDACommand;component/Resources/Icon_OfflineUpload.png")]
+ [Category("活字格安卓容器(HAC)")]
public class OfflinePlusGetPatterns_Async : BaseAsyncCommand
{
-
+ [DisplayName("动作")]
+ [ComboProperty(ValueList = "GetPatterns|ExportRecords|MarkRecordExported|DeleteReadRecords|DeleteProject", DisplayList = "获取设备上的离线表单项目编号列表|导出离线表单数据|标记离线记录已导出|删除已读离线记录|删除离线表单项目")]
+ public string Action { get; set; } = "GetPatterns";
+
+ [FormulaProperty]
+ [DisplayName("项目编号")]
+ public object ProjectId { get; set; }
+
+ [FormulaProperty]
+ [DisplayName("记录编号")]
+ [Description("多个记录编号用英文逗号分隔。标记离线记录已导出时必填;删除已读离线记录时不填,则删除项目下所有已读记录。")]
+ public object RecordIds { get; set; }
+
+ [DisplayName("将离线表单项目编号列表返回到变量")]
+ [ResultToProperty]
+ public string ProjectsResult { get; set; }
+
+ [DisplayName("将离线表单数据返回到变量")]
+ [ResultToProperty]
+ public string ExportResult { get; set; }
+
+ [ServerProperty]
[Browsable(false)]
+ [PageMetadataJsonIgnore]
+ [SaveJsonIgnore]
+ public UploadLimit FileUploadLimit { get; set; } = new UploadLimit();
+
+ [DisplayName("将操作结果返回到变量")]
[ResultToProperty]
- public string ProjectsResult { get; set; } = "projects";
-
+ public string OperationResult { get; set; }
+
public override string ToString()
{
- return "获取已保存项目";
+ return "上传离线表单";
+ }
+
+ public override bool GetDesignerPropertyVisible(string propertyName, CommandScope commandScope)
+ {
+ if (propertyName == nameof(ProjectId))
+ {
+ return Action == "ExportRecords" || Action == "MarkRecordExported" || Action == "DeleteReadRecords" || Action == "DeleteProject";
+ }
+ if (propertyName == nameof(RecordIds))
+ {
+ return Action == "MarkRecordExported" || Action == "DeleteReadRecords";
+ }
+ if (propertyName == nameof(OperationResult))
+ {
+ return Action == "MarkRecordExported" || Action == "DeleteReadRecords" || Action == "DeleteProject";
+ }
+ if (propertyName == nameof(ExportResult))
+ {
+ return Action == "ExportRecords";
+ }
+ if (propertyName == nameof(ProjectsResult))
+ {
+ return Action == "GetPatterns";
+ }
+ return base.GetDesignerPropertyVisible(propertyName, commandScope);
+ }
+ }
+
+ public class UploadLimit : ICloneable, IUploadLimit, ISupportDeclareObjectEmpty
+ {
+ public UploadLimit()
+ {
+ ExtensionFilter = "";
+ SizeLimit = 0;
+ MaxUploadFileCount = 0;
+ }
+
+ [DefaultValue("")]
+ public string ExtensionFilter { get; set; }
+
+ [DefaultValue(0d)]
+ public double SizeLimit { get; set; }
+
+ [DefaultValue(0)]
+ public int MaxUploadFileCount { get; set; }
+
+ public object Clone()
+ {
+ return MemberwiseClone();
+ }
+
+ public bool IsObjectEmpty()
+ {
+ return SizeLimit == 0 && MaxUploadFileCount == 0 && ExtensionFilter == "";
}
}
-}
\ No newline at end of file
+}
diff --git a/Resources/AndroidPDACommand.js b/Resources/AndroidPDACommand.js
index 795ce02920d16e8ce30777fb50325a61e1f85c87..c58bb2758fc155301af1fdc0ba686eb68e11c1cd 100644
--- a/Resources/AndroidPDACommand.js
+++ b/Resources/AndroidPDACommand.js
@@ -1,10 +1,29 @@
var ERROR_NOT_RUN_IN_HAC = "当前APP不支持该命令,这通常是因为APP版本过低。您可以通过在葡萄城技术社区搜索“HAC”下载最新版APP。";
-var HAC_CallFunctionOutOfHAC = function () {
- alert(ERROR_NOT_RUN_IN_HAC);
+var HAC_CallFunctionOutOfHAC = function (debugInfo) {
+ var message = ERROR_NOT_RUN_IN_HAC;
+ if (debugInfo) {
+ message += "\r\n\r\n诊断信息:\r\n" + debugInfo;
+ }
+ alert(message);
}
+var HAC_GetOfflinePlusDebugInfo = function (commandName, stage) {
+ var offlinePlus = window.offlinePlus;
+ var hac = window.HAC;
+ return [
+ "命令:" + commandName,
+ "阶段:" + stage,
+ "window.HAC:" + (hac ? typeof hac : "undefined"),
+ "window.HAC.registryCallback:" + (hac && hac.registryCallback ? typeof hac.registryCallback : "undefined"),
+ "window.offlinePlus:" + (offlinePlus ? typeof offlinePlus : "undefined"),
+ "window.offlinePlus.offlinePlusAddPatternAsync:" + (offlinePlus && offlinePlus.offlinePlusAddPatternAsync ? typeof offlinePlus.offlinePlusAddPatternAsync : "undefined"),
+ "window.offlinePlus.offlinePlusGetPatternsAsync:" + (offlinePlus && offlinePlus.offlinePlusGetPatternsAsync ? typeof offlinePlus.offlinePlusGetPatternsAsync : "undefined"),
+ "location:" + window.location.href
+ ].join("\r\n");
+};
+
var HAC_GenerateCellInfo = function (context, formula) {
var cellLocation = context.getCellLocation(formula);
@@ -18,9 +37,9 @@ var HAC_GenerateCellInfo = function (context, formula) {
return JSON.stringify(cellLocation);
};
-var HAC_GenerateCallbackTicket = function (context, onSuccess) {
+var HAC_GenerateCallbackTicket = function (context, onSuccess, debugInfo) {
if (!window.HAC) {
- HAC_CallFunctionOutOfHAC();
+ HAC_CallFunctionOutOfHAC(debugInfo || "window.HAC is undefined.");
} else {
var ticket = {
@@ -54,6 +73,204 @@ var HAC_ReturnToParam = function (OutParamaterName, data) {
console.log("OutParamaterName was not set, the value is: " + JSON.stringify(data));
}
};
+/**
+ * 将DataURL转换为File对象
+ * @param {*} dataUrl
+ * @param {*} fileName
+ * @returns File对象,或转换失败时返回null
+ */
+var HAC_DataUrlToFile = function (dataUrl, fileName) {
+ var parts = (dataUrl || "").split(",");
+ if (parts.length < 2) {
+ return null;
+ }
+ var header = parts[0];
+ var mimeMatch = header.match(/data:([^;]+);base64/i);
+ var mimeType = mimeMatch ? mimeMatch[1] : "application/octet-stream";
+ var binary = atob(parts.slice(1).join(","));
+ var bytes = new Uint8Array(binary.length);
+ for (var i = 0; i < binary.length; i++) {
+ bytes[i] = binary.charCodeAt(i);
+ }
+ return new File([bytes], fileName || "offlineAttachment", { type: mimeType });
+};
+
+/**
+ * 将字节数格式化为MB字符串
+ */
+var HAC_FormatBytesAsMb = function (bytes) {
+ return (bytes / 1024 / 1024).toFixed(2) + " MB";
+};
+/**
+ * 离线附件上传进度显示组件
+ */
+var HAC_OfflineUploadProgress = {
+ element: null,
+ fill: null,
+ title: null,
+ detail: null,
+ speed: null,
+ ensure: function () {
+ if (this.element) {
+ return;
+ }
+ var root = document.createElement("div");
+ root.style.cssText = "position:fixed;left:0;top:0;right:0;bottom:0;z-index:2147483647;background:rgba(0,0,0,.28);display:flex;align-items:center;justify-content:center;font-family:Arial,'Microsoft YaHei',sans-serif;";
+ root.innerHTML = "" +
+ "
正在上传离线附件
" +
+ "
" +
+ "
" +
+ "
" +
+ "
";
+ document.body.appendChild(root);
+ this.element = root;
+ this.fill = root.querySelector("[data-role='fill']");
+ this.title = root.querySelector("[data-role='title']");
+ this.detail = root.querySelector("[data-role='detail']");
+ this.speed = root.querySelector("[data-role='speed']");
+ },
+ update: function (options) {
+ this.ensure();
+ var percent = Math.max(0, Math.min(100, options.percent || 0));
+ this.fill.style.width = percent.toFixed(1) + "%";
+ this.title.textContent = options.title || "正在上传离线附件";
+ this.detail.textContent = options.detail || "";
+ this.speed.textContent = options.speed || "";
+ },
+ close: function () {
+ if (this.element && this.element.parentNode) {
+ this.element.parentNode.removeChild(this.element);
+ }
+ this.element = null;
+ this.fill = null;
+ this.title = null;
+ this.detail = null;
+ this.speed = null;
+ }
+};
+/**
+ * 将文件上传到服务器临时目录,并返回服务器上的文件标识
+ * @param {*} file
+ * @param {*} uploadLimitId
+ * @param {*} onProgress
+ * @returns Promise,成功时返回服务器上的文件标识,失败时返回错误信息
+ */
+function HAC_UploadFileToTemp(file, uploadLimitId, onProgress) {
+ return new Promise(function (resolve, reject) {
+ var formData = new FormData();
+ formData.append("file", file);
+ formData.append("uploadLimitId", uploadLimitId);
+ formData.append("uploadFolder", "");
+
+ var startTime = new Date().valueOf();
+ var xhr = new XMLHttpRequest();
+ xhr.open("POST", Forguncy.Common.uploadUrl, true);
+ xhr.setRequestHeader("Accept", "application/json");
+ xhr.upload.onprogress = function (event) {
+ if (onProgress && event.lengthComputable) {
+ var elapsedSeconds = Math.max((new Date().valueOf() - startTime) / 1000, 0.1);
+ onProgress(event.loaded, event.total, event.loaded / elapsedSeconds);
+ }
+ };
+ xhr.onload = function () {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ resolve(xhr.responseText);
+ } else {
+ reject(xhr.responseText || xhr.statusText || "上传离线附件失败。");
+ }
+ };
+ xhr.onerror = function () {
+ reject("上传离线附件失败。");
+ };
+ xhr.send(formData);
+ });
+}
+/**
+ * 将上传后的附件值应用到记录中,并更新记录的字段值
+ */
+function HAC_ApplyUploadedAttachmentValue(record, attachment, attachmentValue, uploadedValues) {
+ if (!record || !record.values || !attachment || !attachment.path || attachment.path.length < 3) {
+ return;
+ }
+
+ var fieldId = attachment.path[1];
+ var key = attachment.path[0] + "|" + fieldId;
+ if (!uploadedValues[key]) {
+ uploadedValues[key] = [];
+ }
+ uploadedValues[key].push(attachmentValue);
+ record.values[fieldId] = uploadedValues[key].join("|");
+}
+
+/**
+ * 处理离线导出附件
+ * @param {*} projectId
+ * @param {*} exportData
+ * @param {*} uploadLimitId
+ * @returns Promise,成功时返回处理后的导出数据,失败时返回错误信息
+ */
+async function HAC_ProcessOfflineExportAttachments(projectId, exportData, uploadLimitId) {
+ if (!exportData) {
+ return exportData;
+ }
+ var records = exportData.records || [];
+ if (!exportData.attachments || exportData.attachments.length === 0) {
+ delete exportData.attachments;
+ return exportData;
+ }
+ if (!uploadLimitId) {
+ throw "请设置文件上传限制ID。";
+ }
+ if (!window.offlinePlus || !window.offlinePlus.offlinePlusLoadAttachment) {
+ HAC_CallFunctionOutOfHAC(HAC_GetOfflinePlusDebugInfo("上传离线表单", "调用offlinePlusLoadAttachment"));
+ throw "当前APP不支持读取离线附件。";
+ }
+
+ var uploadedValues = {};
+ HAC_OfflineUploadProgress.update({
+ percent: 0,
+ detail: "准备上传 " + exportData.attachments.length + " 个离线附件",
+ speed: ""
+ });
+ for (var i = 0; i < exportData.attachments.length; i++) {
+ var attachment = exportData.attachments[i];
+ if (!attachment || !attachment.localName || !attachment.path || attachment.path.length < 3) {
+ continue;
+ }
+
+ var fileIndexText = (i + 1) + " / " + exportData.attachments.length;
+ HAC_OfflineUploadProgress.update({
+ percent: exportData.attachments.length === 0 ? 0 : i / exportData.attachments.length * 100,
+ detail: "正在读取离线文件:" + fileIndexText + " " + attachment.localName,
+ speed: ""
+ });
+ var dataUrl = window.offlinePlus.offlinePlusLoadAttachment(projectId, attachment.localName);
+ var fileName = attachment.type === "image" ? attachment.localName : attachment.path[2];
+ var file = HAC_DataUrlToFile(dataUrl, fileName);
+ if (!file) {
+ throw "读取离线附件失败:" + attachment.localName;
+ }
+
+ var attachmentValue = await HAC_UploadFileToTemp(file, uploadLimitId, function (loaded, total, bytesPerSecond) {
+ HAC_OfflineUploadProgress.update({
+ percent: (i + (total > 0 ? loaded / total : 0)) / exportData.attachments.length * 100,
+ detail: "正在上传:" + fileIndexText + " " + file.name + "," + HAC_FormatBytesAsMb(loaded) + " / " + HAC_FormatBytesAsMb(total),
+ speed: "速度:" + HAC_FormatBytesAsMb(bytesPerSecond) + "/s"
+ });
+ });
+ var record = records.find(function (record) {
+ return record && record.recordId === attachment.path[0];
+ });
+ HAC_ApplyUploadedAttachmentValue(record, attachment, attachmentValue, uploadedValues);
+ }
+ HAC_OfflineUploadProgress.update({
+ percent: 100,
+ detail: "正在生成导出数据",
+ speed: ""
+ });
+ delete exportData.attachments;
+ return exportData;
+}
var HAC_DothanPrinterOp = function (callback) {
if (window.dothanPrinter) {
@@ -1386,6 +1603,31 @@ var Device_Info_Command = (function (_super) {
Forguncy.CommandFactory.registerCommand("AndroidPDACommand.Device_Info, AndroidPDACommand", Device_Info_Command);
+var Device_Info_Json_Command = (function (_super) {
+ __extends(Device_Info_Json_Command, _super);
+ function Device_Info_Json_Command() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+
+ Device_Info_Json_Command.prototype.execute = function () {
+ var params = this.CommandParam;
+ var pName = params.DeviceInfoJson;
+
+ if (window.device && window.device.getDeviceInfo) {
+ var value = window.device.getDeviceInfo();
+
+ HAC_ReturnToParam(pName, value);
+ } else {
+ HAC_CallFunctionOutOfHAC();
+ HAC_ReturnToParam(pName, "");
+ }
+ };
+
+ return Device_Info_Json_Command;
+}(Forguncy.CommandBase));
+
+Forguncy.CommandFactory.registerCommand("AndroidPDACommand.Device_Info_Json, AndroidPDACommand", Device_Info_Json_Command);
+
var BLE_Scan_Command = (function (_super) {
__extends(BLE_Scan_Command, _super);
function BLE_Scan_Command() {
@@ -2347,7 +2589,7 @@ var GenericBroadcast_Stop_Command = (function (_super) {
var params = this.CommandParam;
var uuid = this.evaluateFormula(params.HandlerID);
-
+
if (window.broadcast && window.broadcast.stopReceiving) {
window.broadcast.stopReceiving(uuid);
@@ -2428,14 +2670,14 @@ var OnKeyDown_Listen_Start_Async_Command = (function (_super) {
locationString: "执行window.onKeyDownListen.startOnKeyDownListenAsync的回调"
});
});
-
+
if (window.onKeyDownListen && window.onKeyDownListen.startOnKeyDownListenAsync) {
window.onKeyDownListen.startOnKeyDownListenAsync(ticket, theKey, isCover);
} else {
HAC_CallFunctionOutOfHAC();
}
}
-
+
return OnKeyDown_Listen_Start_Async_Command;
}(Forguncy.CommandBase));
@@ -2451,14 +2693,14 @@ var OnKeyDown_Listen_Stop_Command = (function (_super) {
var params = this.CommandParam;
var theKey = this.evaluateFormula(params.TheKey);
-
+
if (window.onKeyDownListen && window.onKeyDownListen.stopOnKeyDownListen) {
window.onKeyDownListen.stopOnKeyDownListen(theKey);
} else {
HAC_CallFunctionOutOfHAC();
}
};
-
+
return OnKeyDown_Listen_Stop_Command;
}(Forguncy.CommandBase));
@@ -2569,12 +2811,277 @@ var OfflinePlusAddPattern_Async_Command = (function (_super) {
return _super !== null && _super.apply(this, arguments) || this;
}
- OfflinePlusAddPattern_Async_Command.prototype.execute = function () {
+ OfflinePlusAddPattern_Async_Command.prototype.execute = async function () {
let me = this;
let params = this.CommandParam;
+ let patternParamJson = "";
+
+ function evaluate(value) {
+ if (value === undefined || value === null) {
+ return value;
+ }
+ return me.evaluateFormula(value);
+ }
+
+ function getList(value) {
+ return Array.isArray(value) ? value : [];
+ }
+
+ function buildSelectOptions(options) {
+ return getList(options).map(function (option) {
+ return {
+ value: evaluate(option.Value),
+ label: evaluate(option.Label)
+ };
+ });
+ }
+
+ function buildCheckOptions(options) {
+ if (!options) {
+ return undefined;
+ }
+
+ var checkOptions = {};
+ var minLength = evaluate(options.MinLength);
+ var maxLength = evaluate(options.MaxLength);
+ var regexPattern = evaluate(options.RegexPattern);
+ if (minLength !== undefined && minLength !== null && minLength !== "") {
+ checkOptions.minLength = minLength;
+ }
+ if (maxLength !== undefined && maxLength !== null && maxLength !== "") {
+ checkOptions.maxLength = maxLength;
+ }
+ if (regexPattern !== undefined && regexPattern !== null && regexPattern !== "") {
+ checkOptions.regexPattern = regexPattern;
+ }
+ return Object.keys(checkOptions).length > 0 ? checkOptions : undefined;
+ }
+
+ function buildImageCompression(options) {
+ if (!options) {
+ return undefined;
+ }
+
+ var compression = {};
+ var maxLongEdge = evaluate(options.MaxLongEdge);
+ var jpegQuality = evaluate(options.JpegQuality);
+ var maxFileSizeKb = evaluate(options.MaxFileSizeKb);
+ var minQuality = evaluate(options.MinQuality);
+ compression.enableCompression = !!options.EnableCompression;
+ if (maxLongEdge !== undefined && maxLongEdge !== null && maxLongEdge !== "") {
+ compression.maxLongEdge = maxLongEdge;
+ }
+ if (jpegQuality !== undefined && jpegQuality !== null && jpegQuality !== "") {
+ compression.jpegQuality = jpegQuality;
+ }
+ if (maxFileSizeKb !== undefined && maxFileSizeKb !== null && maxFileSizeKb !== "") {
+ compression.maxFileSizeKb = maxFileSizeKb;
+ }
+ if (minQuality !== undefined && minQuality !== null && minQuality !== "") {
+ compression.minQuality = minQuality;
+ }
+ return Object.keys(compression).length > 0 ? compression : undefined;
+ }
+
+ function buildImageWatermark(options) {
+ if (!options) {
+ return undefined;
+ }
+
+ var fields = getList(options.Fields);
+ if (!options.EnableTimestamp && fields.length === 0) {
+ return undefined;
+ }
+
+ var watermark = {};
+ var items = fields.map(function (field) {
+ return {
+ key: field.Key,
+ value: evaluate(field.Value)
+ };
+ });
+
+ if (options.EnableTimestamp) {
+ watermark.enableTimestamp = true;
+ }
+ if (items.length > 0) {
+ watermark.items = items;
+ }
+ return Object.keys(watermark).length > 0 ? watermark : undefined;
+ }
+
+ function buildFileItemConfig(options) {
+ if (!options) {
+ return undefined;
+ }
+
+ var config = {};
+ var maxCount = evaluate(options.MaxCount);
+ var allowedExtensions = evaluate(options.AllowedExtensions);
+ var maxFileSizeKb = evaluate(options.MaxFileSizeKb);
+ if (maxCount !== undefined && maxCount !== null && maxCount !== "") {
+ config.maxCount = maxCount;
+ }
+ if (allowedExtensions !== undefined && allowedExtensions !== null && allowedExtensions !== "") {
+ config.allowedExtensions = allowedExtensions;
+ }
+ if (maxFileSizeKb !== undefined && maxFileSizeKb !== null && maxFileSizeKb !== "") {
+ config.maxFileSizeKb = maxFileSizeKb;
+ }
+ return Object.keys(config).length > 0 ? config : undefined;
+ }
+
+ var fieldTypeSpecs = {
+ textItem: {
+ apply: function (field, node) {
+ var checkOptions = buildCheckOptions(node.CheckOptions);
+ if (checkOptions) {
+ field.checkOptions = checkOptions;
+ }
+ }
+ },
+ passwordItem: {
+ apply: function (field, node) {
+ var checkOptions = buildCheckOptions(node.CheckOptions);
+ if (checkOptions) {
+ field.checkOptions = checkOptions;
+ }
+ }
+ },
+ selectItem: {
+ apply: function (field, node) {
+ var selectOptions = buildSelectOptions(node.SelectOptionsList);
+ if (selectOptions.length > 0) {
+ field.options = selectOptions;
+ }
+ }
+ },
+ timePicker: {
+ apply: function (field, node) {
+ if (node.IncludeSeconds) {
+ field.includeSeconds = true;
+ }
+ }
+ },
+ imageItem: {
+ apply: function (field, node) {
+ var maxCount = evaluate(node.MaxCount);
+ var compression = buildImageCompression(node.CompressionOptions);
+ var watermark = buildImageWatermark(node.WatermarkOptions);
+ if (maxCount !== undefined && maxCount !== null && maxCount !== "") {
+ field.maxCount = maxCount;
+ }
+ if (node.AllowImageUpload) {
+ field.allowImageUpload = true;
+ }
+ if (compression) {
+ field.compression = compression;
+ }
+ if (watermark) {
+ field.watermark = watermark;
+ }
+ }
+ },
+ fileItem: {
+ apply: function (field, node) {
+ var config = buildFileItemConfig(node.FileItemConfig);
+ if (config) {
+ field.fileItemConfig = config;
+ }
+ }
+ }
+ };
+
+ function applyFieldTypeSpec(field, node) {
+ var spec = fieldTypeSpecs[node.ItemType];
+ if (spec && spec.apply) {
+ spec.apply(field, node);
+ }
+ }
+
+ function buildField(node) {
+ var field = {
+ itemId: evaluate(node.ItemId),
+ itemType: node.ItemType,
+ title: evaluate(node.Title),
+ hint: evaluate(node.Hint),
+ required: !!node.Required
+ };
+
+ var value = evaluate(node.Value);
+ if (value !== undefined && value !== null && value !== "") {
+ field.value = value;
+ }
+ applyFieldTypeSpec(field, node);
+ return field;
+ }
+
+ function buildNodes(nodes) {
+ return getList(nodes).map(function (node) {
+ var nodeType = node.NodeType || "group";
+ var children = getList(node.Children);
+
+ if (nodeType !== "group" && children.length > 0) {
+ console.warn("离线表单节点不是分组,但包含子节点。", node);
+ }
+
+ if (nodeType === "field") {
+ return {
+ nodeType: "field",
+ title: node.Text,
+ field: buildField(node)
+ };
+ }
+
+ if (nodeType === "text") {
+ return {
+ nodeType: "text",
+ title: node.Text,
+ content: evaluate(node.Content)
+ };
+ }
+
+ return {
+ nodeType: "group",
+ title: node.Text,
+ defaultCollapsed: !!node.DefaultCollapsed,
+ children: buildNodes(children)
+ };
+ });
+ }
+
+ function buildSteps(steps) {
+ return getList(steps).map(function (step) {
+ return {
+ stepId: evaluate(step.StepId),
+ title: evaluate(step.Title),
+ items: buildNodes(step.Items)
+ };
+ });
+ }
+
+ function getManualPdfUrl() {
+ if (params.ManualAttachmentCell === undefined || params.ManualAttachmentCell === null || params.ManualAttachmentCell === "") {
+ return undefined;
+ }
+
+ var manualValue = evaluate(params.ManualAttachmentCell);
+ if (!manualValue) {
+ return undefined;
+ }
+
+ var fileId = (manualValue + "").split("|")[0];
+ if (!fileId) {
+ console.warn("手册附件单元格没有文件标识。", manualValue);
+ return undefined;
+ }
+
+ return Forguncy.Helper.SpecialPath.getFileDownloadUrl(fileId);
+ }
let _ticket = HAC_GenerateCallbackTicket(me, function (payload, payload2) {
+ alert("离线表单项目设置成功\r\n\r\nJSON Schema:\r\n" + patternParamJson);
me.CommandExecutor.excuteCommand(me.CommandParam.CommandList, {
runTimePageName: me.CommandExecutingInfo.runTimePageName,
commandID: new Date().valueOf().toString(),
@@ -2584,22 +3091,27 @@ var OfflinePlusAddPattern_Async_Command = (function (_super) {
},
locationString: "执行window.offlinePlus.offlinePlusAddPattern"
});
- });
-
+ }, HAC_GetOfflinePlusDebugInfo("添加离线表单项目", "生成回调ticket"));
+ const steps = buildSteps(params.Steps);
let patternParam = {
ticket: _ticket,
patternId: this.evaluateFormula(params.PatternId),
+ schemaVersion: this.evaluateFormula(params.SchemaVersion),
title: this.evaluateFormula(params.Title),
description: this.evaluateFormula(params.Description),
- formItems: params.FormItems
+ steps: steps
};
+ const signatureBase64 = params.SignatureAttachmentCell === undefined || params.SignatureAttachmentCell === null || params.SignatureAttachmentCell === ""
+ ? ""
+ : this.evaluateFormula(params.SignatureAttachmentCell);
+ var manualPdfUrl = getManualPdfUrl();
+ patternParamJson = JSON.stringify(patternParam, null, 2);
console.log(patternParam);
if (window.offlinePlus && window.offlinePlus.offlinePlusAddPatternAsync) {
-
- window.offlinePlus.offlinePlusAddPatternAsync(JSON.stringify(patternParam));
+ window.offlinePlus.offlinePlusAddPatternAsync(patternParamJson, manualPdfUrl || "", signatureBase64 || "");
} else {
- HAC_CallFunctionOutOfHAC();
+ HAC_CallFunctionOutOfHAC(HAC_GetOfflinePlusDebugInfo("添加离线表单项目", "调用offlinePlusAddPatternAsync"));
}
};
@@ -2616,10 +3128,141 @@ var OfflinePlusGetPatterns_Async_Command = (function (_super) {
}
OfflinePlusGetPatterns_Async_Command.prototype.execute = function () {
+ var params = this.CommandParam;
+ var action = params.Action || "GetPatterns";
+
+ if (action === "ExportRecords") {
+ var projectId = this.evaluateFormula(params.ProjectId);
+ var fileUploadLimit = (params.ServerPropertiesId && params.ServerPropertiesId.FileUploadLimit) || "";
+ let me = this;
+ let ticket = HAC_GenerateCallbackTicket(me, async function (payload, payload2) {
+ try {
+ var exportData = JSON.parse(payload);
+ if (exportData) {
+ exportData = await HAC_ProcessOfflineExportAttachments(projectId, exportData, fileUploadLimit);
+ payload = JSON.stringify(exportData);
+ }
+ HAC_ReturnToParam(params.ExportResult, payload);
+ me.CommandExecutor.excuteCommand(me.CommandParam.CommandList, {
+ runTimePageName: me.CommandExecutingInfo.runTimePageName,
+ commandID: new Date().valueOf().toString(),
+ initParams: {
+ "ExportResult": payload,
+ "IsSuccess": true,
+ "Error": ""
+ },
+ locationString: "执行window.offlinePlus.offlinePlusExportRecordsAsync"
+ });
+ } catch (e) {
+ me.CommandExecutor.excuteCommand(me.CommandParam.CommandList, {
+ runTimePageName: me.CommandExecutingInfo.runTimePageName,
+ commandID: new Date().valueOf().toString(),
+ initParams: {
+ "ExportResult": payload,
+ "IsSuccess": false,
+ "Error": e ? e.toString() : "导出离线附件失败。"
+ },
+ locationString: "处理离线附件上传时出错"
+ });
+ } finally {
+ HAC_OfflineUploadProgress.close();
+ }
+ }, HAC_GetOfflinePlusDebugInfo("上传离线表单", "生成导出数据回调ticket"));
+
+ if (window.offlinePlus && window.offlinePlus.offlinePlusExportRecordsAsync) {
+ window.offlinePlus.offlinePlusExportRecordsAsync(projectId, ticket);
+ } else {
+ HAC_CallFunctionOutOfHAC(HAC_GetOfflinePlusDebugInfo("上传离线表单", "调用offlinePlusExportRecordsAsync"));
+ }
+ return;
+ }
+
+ if (action === "MarkRecordExported") {
+ var projectId = this.evaluateFormula(params.ProjectId);
+ var recordIds = this.evaluateFormula(params.RecordIds);
+ let me = this;
+ let ticket = HAC_GenerateCallbackTicket(me, function (payload, payload2) {
+ HAC_ReturnToParam(params.OperationResult, payload);
+ me.CommandExecutor.excuteCommand(me.CommandParam.CommandList, {
+ runTimePageName: me.CommandExecutingInfo.runTimePageName,
+ commandID: new Date().valueOf().toString(),
+ initParams: {
+ "OperationResult": payload,
+ "IsSuccess": true,
+ "Error": ""
+ },
+ locationString: "执行window.offlinePlus.offlinePlusMarkRecordExportedAsync"
+ });
+ }, HAC_GetOfflinePlusDebugInfo("上传离线表单", "生成标记导出回调ticket"));
+
+ if (window.offlinePlus && window.offlinePlus.offlinePlusMarkRecordExportedAsync) {
+ window.offlinePlus.offlinePlusMarkRecordExportedAsync(projectId, recordIds, ticket);
+ } else {
+ HAC_CallFunctionOutOfHAC(HAC_GetOfflinePlusDebugInfo("上传离线表单", "调用offlinePlusMarkRecordExportedAsync"));
+ }
+ return;
+ }
+
+ if (action === "DeleteReadRecords") {
+ var projectId = this.evaluateFormula(params.ProjectId);
+ var recordIds = this.evaluateFormula(params.RecordIds);
+ let me = this;
+ let ticket = HAC_GenerateCallbackTicket(me, function (payload, payload2) {
+ HAC_ReturnToParam(params.OperationResult, payload);
+ me.CommandExecutor.excuteCommand(me.CommandParam.CommandList, {
+ runTimePageName: me.CommandExecutingInfo.runTimePageName,
+ commandID: new Date().valueOf().toString(),
+ initParams: {
+ "OperationResult": payload,
+ "IsSuccess": true,
+ "Error": ""
+ },
+ locationString: "执行window.offlinePlus.offlinePlusDeleteReadRecordsAsync"
+ });
+ }, HAC_GetOfflinePlusDebugInfo("上传离线表单", "生成删除已读记录回调ticket"));
+
+ if (window.offlinePlus && window.offlinePlus.offlinePlusDeleteReadRecordsAsync) {
+ window.offlinePlus.offlinePlusDeleteReadRecordsAsync(projectId, recordIds, ticket);
+ } else {
+ HAC_CallFunctionOutOfHAC(HAC_GetOfflinePlusDebugInfo("上传离线表单", "调用offlinePlusDeleteReadRecordsAsync"));
+ }
+ return;
+ }
+
+ if (action === "DeleteProject") {
+ var projectId = this.evaluateFormula(params.ProjectId);
+ let me = this;
+ let ticket = HAC_GenerateCallbackTicket(me, function (payload, payload2) {
+ HAC_ReturnToParam(params.OperationResult, payload);
+ me.CommandExecutor.excuteCommand(me.CommandParam.CommandList, {
+ runTimePageName: me.CommandExecutingInfo.runTimePageName,
+ commandID: new Date().valueOf().toString(),
+ initParams: {
+ "OperationResult": payload,
+ "IsSuccess": true,
+ "Error": ""
+ },
+ locationString: "执行window.offlinePlus.offlinePlusDeleteProjectAsync"
+ });
+ }, HAC_GetOfflinePlusDebugInfo("上传离线表单", "生成删除离线表单项目回调ticket"));
+
+ if (window.offlinePlus && window.offlinePlus.offlinePlusDeleteProjectAsync) {
+ window.offlinePlus.offlinePlusDeleteProjectAsync(projectId, ticket);
+ } else {
+ HAC_CallFunctionOutOfHAC(HAC_GetOfflinePlusDebugInfo("上传离线表单", "调用offlinePlusDeleteProjectAsync"));
+ }
+ return;
+ }
+
+ if (action !== "GetPatterns") {
+ alert("不支持的离线表单上传动作:" + action);
+ return;
+ }
let me = this;
let ticket = HAC_GenerateCallbackTicket(me, function (payload, payload2) {
+ HAC_ReturnToParam(params.ProjectsResult, payload);
me.CommandExecutor.excuteCommand(me.CommandParam.CommandList, {
runTimePageName: me.CommandExecutingInfo.runTimePageName,
commandID: new Date().valueOf().toString(),
@@ -2630,17 +3273,15 @@ var OfflinePlusGetPatterns_Async_Command = (function (_super) {
},
locationString: "执行window.offlinePlus.offlinePlusGetPatternsAsync"
});
- });
+ }, HAC_GetOfflinePlusDebugInfo("上传离线表单", "生成回调ticket"));
if (window.offlinePlus && window.offlinePlus.offlinePlusGetPatternsAsync) {
window.offlinePlus.offlinePlusGetPatternsAsync(ticket);
} else {
- HAC_CallFunctionOutOfHAC();
+ HAC_CallFunctionOutOfHAC(HAC_GetOfflinePlusDebugInfo("上传离线表单", "调用offlinePlusGetPatternsAsync"));
}
-
};
-
return OfflinePlusGetPatterns_Async_Command;
}(Forguncy.CommandBase));
diff --git a/Resources/Icon_OfflineDownload.png b/Resources/Icon_OfflineDownload.png
new file mode 100644
index 0000000000000000000000000000000000000000..1295a66c444353576d3580da122e425f19b457b9
Binary files /dev/null and b/Resources/Icon_OfflineDownload.png differ
diff --git a/Resources/Icon_OfflineUpload.png b/Resources/Icon_OfflineUpload.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb7876aa0535f3281c9228c20470eeb39031e1e6
Binary files /dev/null and b/Resources/Icon_OfflineUpload.png differ