二开插件:移动端上传的文件和图片,直接保存到pc单据对应的字段中原创
金蝶云社区-暗夜
暗夜
20人赞赏了该文章 1708次浏览 未经作者许可,禁止转载编辑于2021年10月20日 16:41:44

      经常收到小伙伴的反馈,移动表单,移动单据中上传的附件或图片,怎么保存到pc端目标单据的指定字段中呢?今天通过一个插件示例,来完成该工作;
      适用范围:在移动单据、移动表单中,将移动端上传的附件和图片,直接与pc端对应的附件文件服务器,附件数据库,图片文件服务器,图片数据库相关联;
      温馨提示:如果仅需要保存到pc端单据的附件列表中,那么直接使用单据附件控件即可;仅附件数据库支持多选,其他控件仅支持单选;
      准备工作:如果仅需要关联附件文件服务器,附件数据库,那么7.5以上版本均可;如果关联图片文件服务器,图片数据库,则需要升级2021年3月份及以上的补丁;
      需求描述(示例):测试单据中包含:附件文件服务器,附件数据库,图片文件服务器,图片数据库4个字段,要求在移动表单中上传的文件和图片,与在测试单据中上传保持一致,数据互通; 测试单据示例:  
image.png
     移动表单设计:如下图所示,包含附件控件和图片控件,需要勾选允许上传:
image.png 
    
image.png
     

      pc端运行效果图:
image.png
image.png
      插件代码:

using Kingdee.BOS.Core;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.FileServer.Core;
using Kingdee.BOS.FileServer.Core.Object;
using Kingdee.BOS.FileServer.ProxyService;
using Kingdee.BOS.JSON;
using Kingdee.BOS.KDThread;
using Kingdee.BOS.Mobile.Metadata.ControlDataEntity;
using Kingdee.BOS.Mobile.PlugIn;
using Kingdee.BOS.Mobile.PlugIn.ControlModel;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
namespace Kingdee.BOS.Mobile.FormPlugIns.Test
{
    /// <summary>
    /// 附件上传测试
    /// </summary>
    /// <remarks>
    /// 附件上传涉及以下步骤:
    /// 1. 附件控件将选取文件拷贝到临时目录
    /// 2. 触发AfterMobileUpload函数并传入所需参数
    /// 3. 从临时目录将文件保存至数据库
    /// </remarks>
    [Description("测试附件字段上传--与pc单据字段关联")]
    public class TestAccessoryFieldUpload : AbstractMobilePlugin
    {
        /// <summary>
        /// 上传类型
        /// </summary>
        private enum SubmitType
        {
            FileServer,
            FileDatabase,
            ImageServer,
            ImageDatabase
        }
        private SubmitType submitType;
        /// <summary>
        /// 表单上的按钮点击事件
        /// </summary>
        /// <param name="e"></param>
        public override void ButtonClick(Core.DynamicForm.PlugIn.Args.ButtonClickEventArgs e)
        {
            if ("FButtonFileServer".EqualsIgnoreCase(e.Key))
            {
                // 检查是否启用了文件服务器
                if (!Kingdee.BOS.ServiceHelper.FileServer.FileServerHelper.UsedFileServer(this.Context))
                {
                    this.View.ShowMessage("未启用文件服务器,无法实现上传。");
                    return;
                }
                submitType = SubmitType.FileServer;
                this.View.GetControl<FileUploadControl>("FFileUpload").UploadFieldBatch();
            }
            else if ("FButtonFileDatabase".EqualsIgnoreCase(e.Key))
            {
                submitType = SubmitType.FileDatabase;
                // 将附件上传至临时目录
                this.View.GetControl<FileUploadControl>("FFileUpload").UploadFieldBatch();
            }
            else if ("FButtonImageServer".EqualsIgnoreCase(e.Key))
            {
                // 检查是否启用了文件服务器
                if (!Kingdee.BOS.ServiceHelper.FileServer.FileServerHelper.UsedFileServer(this.Context))
                {
                    this.View.ShowMessage("未启用文件服务器,无法实现上传。");
                    return;
                }
                submitType = SubmitType.ImageServer;
                this.View.GetControl<ImageUploadControl>("FImageUpload").UploadFieldBatch();
            }
            else if ("FButtonImageDatabase".EqualsIgnoreCase(e.Key))
            {
                submitType = SubmitType.ImageDatabase;
                // 将图片上传至临时目录
                this.View.GetControl<ImageUploadControl>("FImageUpload").UploadFieldBatch();
            }
            base.ButtonClick(e);
        }
        /// <summary>
        /// 通过二开插件直接将上传的文件保存到pc单据对应的字段中
        /// </summary>
        /// <param name="e"></param>
        public override void AfterMobileUpload(PlugIn.Args.MobileUploadEventArgs e)
        {
            string _FormId  = "kd_FlexTest"; // 目标单据唯一标识,即formid
            string _InterID = "100016"; // 单据内码,这个ID将作为我们下载的识别标识
            string fileServerName = "F_MOB_FileServer"; //单据中文件服务器控件的字段名
            string fileDatabaseName = "F_MOB_FileDatabase"; //单据中文件数据库控件的字段名
            string imageServerName = "F_MOB_ImageServer"; //单据中图片服务器控件的字段名
            string imageDatabaseName = "F_MOB_ImageDatabase"; //单据中图片数据库控件的字段名
 
            var businessInfo = ((FormMetadata)MetaDataServiceHelper.Load(this.Context, _FormId)).BusinessInfo;
            var dyn = BusinessDataServiceHelper.LoadSingle(this.Context, _InterID, businessInfo.GetDynamicObjectType());
            dyn = dyn ?? new DynamicObject(businessInfo.GetDynamicObjectType());
            // 获取文件上传的临时目录
            string tempDirPath = HttpContext.Current.Request.PhysicalApplicationPath + KeyConst.TEMPFILEPATH;
            //仅文件数据库支持上传多个文件,其他仅支持上传一个文件
            if (submitType == SubmitType.FileDatabase) //上传附件至数据库
            {
                StringBuilder sb = new StringBuilder();
                JSONArray fileArray = new JSONArray();
                foreach (FiledUploadEntity file in e.FileNameArray)
                {
                    if (!file.IsSuccess) continue; // 检查文件是否上传成功
                    var filePath = System.IO.Path.Combine(tempDirPath, file.FileName); // 检查文件是否存在
                    if (!System.IO.File.Exists(filePath)) continue;
                    JSONObject fileObject = new JSONObject();
                    var dataBuff = System.IO.File.ReadAllBytes(filePath);
                    string fileName = Guid.NewGuid().ToString() + " " + file.OldName;
                    fileObject.Put("ServerFileName", fileName);
                    fileObject.Put("FileName", file.OldName);
                    fileObject.Put("FileLength", dataBuff.Length);
                    fileObject.Put("FileBytesLength", dataBuff.Length);
                    fileObject.Put("FileContent", dataBuff);
                    fileArray.Add(fileObject);
                }
                if (fileArray.Count == 0) return;
                dyn[fileDatabaseName] = SerializatonUtil.SerializeToBase64(fileArray);
                BusinessDataServiceHelper.Save(this.Context, businessInfo, dyn);
                sb.AppendLine();
                sb.AppendLine("上传成功"); 
                this.Model.SetValue("FFileLog", sb.ToString());
            }
            else
            {
                string str = string.Empty;
                var file = e.FileNameArray[0];
                if (file == null || !file.IsSuccess) str = "上传失败"; // 检查文件是否上传成功
                var filePath = System.IO.Path.Combine(tempDirPath, file.FileName);
                if (!System.IO.File.Exists(filePath)) str = "文件不存在"; // 检查文件是否存在
                var dataBuff = System.IO.File.ReadAllBytes(filePath);
                if (submitType == SubmitType.FileServer)  //上传附件至文件服务器
                {
                    var result = this.UploadAttachment(file.FileName, dataBuff); // 将数据上传至文件服务器,并返回上传结果
                    if (result.Success)
                    {
                        dyn[fileServerName] = result.FileId;
                        BusinessDataServiceHelper.Save(this.Context, businessInfo, dyn);
                        str = "上传成功";
                    }
                    else
                    {
                        str = string.Format("附件:{0},上传失败:{1}", file.FileName, result.Message); // 上传失败,收集失败信息
                    }
                    this.Model.SetValue("FFileLog", str);
                }
                else if (submitType == SubmitType.ImageServer)  //上传图片至文件服务器
                {
                    var result = this.UploadAttachment(file.FileName, dataBuff); // 将数据上传至文件服务器,并返回上传结果
                    if (result.Success)
                    {
                        dyn[imageServerName] = result.FileId;
                        BusinessDataServiceHelper.Save(this.Context, businessInfo, dyn);
                        str = "上传成功";
                    }
                    else
                    {
                        str = string.Format("附件:{0},上传失败:{1}", file.FileName, result.Message); // 上传失败,收集失败信息
                    }
                    this.Model.SetValue("FImageLog", str);
                }
                else if (submitType == SubmitType.ImageDatabase)  //上传图片至数据库
                {
                    dyn[imageDatabaseName] = dataBuff;
                    BusinessDataServiceHelper.Save(this.Context, businessInfo, dyn);
                    str = "上传成功";
                }
            }
            base.AfterMobileUpload(e);
        }
        /// <summary>
        /// 上传至文件服务器的方法
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="dataBuff"></param>
        /// <returns></returns>
        private FileUploadResult UploadAttachment(string fileName, byte[] dataBuff)
        {
            // 初始化上传下载服务
            var service = new UpDownloadService();
            int len = 0, less = 0;
            string fileId = null;
            byte[] buff = null;
            while (len < dataBuff.Length)
            {
                // 文件服务器采用分段上传,每次上传4096字节, 最后一次如果不够则上传剩余长度
                less = (dataBuff.Length - len) >= 4096 ? 4096 : (dataBuff.Length - len);
                buff = new byte[less];
                Array.Copy(dataBuff, len, buff, 0, less);
                len += less;
                using (System.IO.MemoryStream ms = new System.IO.MemoryStream(buff))
                {
                    TFileInfo tFile = new TFileInfo()
                    {
                        FileId = fileId,
                        FileName = fileName,
                        CTX = this.Context,
                        Last = len >= dataBuff.Length,//标记是否为文件的最后一个片段 
                        Stream = ms
                    };
                    var result = submitType == SubmitType.FileServer ? service.UploadAttachment(tFile) : service.UploadImage(tFile);
                    // 注意点:上传时fileId传入null为新文件开始,会返回一个文件的fileId,后续采用这个fileId标识均为同一文件的不同片段。
                    fileId = result.FileId;
                    if (!result.Success)
                    {
                        return result;
                    }
                }
            }
            return new FileUploadResult()
            {
                Success = true,
                FileId = fileId
            };
        }
    }
}




赞 20