电脑桌面
添加蚂蚁七词文库到电脑桌面
安装后可以在桌面快捷访问

掌上报销单据头附件二开方案

来源:金蝶云社区作者:金蝶2024-09-232

掌上报销单据头附件二开方案

【应用场景】

客户在PC端单据头增加了附件字段,需要在掌上报销单据头也额外增加相关功能

【案例演示】

PC端费用报销与掌上报销单据头与单据体的映射关系:https://vip.kingdee.com/article/439370655386174720?productLineId=1&isKnowledge=2


【实现步骤】

1、  更新了多选附件(文件服务)控件的相关示例代码。

2、  本文示例代码以勾选【上传按钮】为基础来实现。如果需要勾选【自动上传】,需要自行调整UploadAttachFiles的逻辑。


掌上报销单据头附件二开步骤主要分为三步:

一、BOS设计器往掌上报销移动表单:掌上报销V3_费用报销单ER_MBReimb_ExpReimbV3里面添加附件上传控件,自行调整样式,勾选【上传按钮】

二、往PC端单据:费用报销单ER_ExpReimbursement增加附件字段,以多选附件(文件服务)为例,往单据头添加多选附件(文件服务)控件

三、需要处理:移动端上传的附件,直接保存到pc单据对应的字段中,pc端上传的单据头附件,在移动端显示。

二开掌上报销移动表单插件:掌上报销V3_费用报销单ER_MBReimb_ExpReimbV3,重写下面方法AfterBindData、AfterMobileUpload(根据移动端控件标识判断是否调用基类方法)

步骤一:单独针对移动端单据头,能够正常显示下载PC端上传的附件。

移动端绑定历史上传附件:

 /// <summary>
        /// 文件FileId与移动端附件控件展示时用的文件名的映射(附件(数据库)专用)
        /// </summary>
        Dictionary<string, string> FieIdToDisplayFileName = new Dictionary<string, string>();
 
        /// <summary>
        /// 多选附件(文件服务)存储在数据库里的文件信息
        /// </summary>
        JSONArray Files = new JSONArray();
 
        private SubmitType submitType;
 
        public override void AfterBindData(EventArgs e)
        {
            base.AfterBindData(e);
            BindValue();
        }
        private void BindValue()
        {
            var pkValue = BillView.Model.GetPKValue();
            if (pkValue.IsEmptyPrimaryKey())
            {
                return;
            }
 
            string _FormId = "ER_ExpReimbursement"; // 目标单据唯一标识,即formid
            string _InterID = pkValue.ToString(); // 单据内码,这个ID将作为我们下载的识别标识
            //string controlKey = "F_MOB_FileServer"; //单据中附件(文件服务)控件的字段名
            //string controlKey = "F_MOB_FileDatabase"; //单据中附件(数据库)控件的字段名
            //string controlKey = "F_MOB_ImageServer"; //单据中图片(文件服务)控件的字段名
            //string controlKey = "F_MOB_ImageDatabase"; //单据中图片(数据库)控件的字段名
            //string controlKey = "F_MOB_FileServerMulti"; //单据中多选附件(文件服务)控件的字段名
            string controlKey = "F_MOB_FileServerMulti";
            var businessInfo = ((FormMetadata)MetaDataServiceHelper.Load(this.Context, _FormId)).BusinessInfo;
            var dyn = BusinessDataServiceHelper.LoadSingle(this.Context, _InterID, businessInfo.GetDynamicObjectType());
            if (dyn == null) return;
            var dynFile = dyn[controlKey];
            if (dynFile == null) return;
            List<File> files = new List<File>();
            string path = HttpContext.Current.Request.PhysicalApplicationPath + KeyConst.TEMPFILEPATH; // 获取文件上传的临时目录
 
            // 下面是pc端不同附件字段对应的移动端显示附件的方式,可根据业务需要来选择
            if (controlKey == "F_MOB_FileDatabase") //pc单据对应的控件类型为附件(数据库)
            {
                FieIdToDisplayFileName = new Dictionary<string, string>();
                string fieldValue = dynFile.ToString(); //附件(数据库),实际存储的是转成base64字符串的json数组
                JSONArray fileArray = fieldValue.IsEmpty() ? new JSONArray() : SerializatonUtil.DeserializeFromBase64<JSONArray>(fieldValue);
                foreach (JSONObject json in fileArray)
                {
                    string fileId = string.Empty;
                    string serverFileName = json.GetString("ServerFileName");
                    string fileName = json.GetString("FileName");
                    string fileType = fileName.Substring(fileName.LastIndexOf(".") + 1);
 
                    //附件(数据库)储存方式,根据byte数据组保存文件到临时目录,返回文件名给前端,前端根据文件名获取数据                   
                    int length = serverFileName.IndexOf(" ") > -1 ? serverFileName.IndexOf(" ") : serverFileName.Length;
                    fileId = serverFileName.Substring(0, length); //附件(数据库),serverFileName为fileid+空格+文件名+后缀,需要截取
                    fileName = CommonFunctionUtil.FilterOpSysInvalidCharacterForFileName(fileName);
                    var displayFileName = CommonFunctionUtil.GetFileName(this.Context, fileId, fileName); //附件控件展示时用的文件名
                    string filePath = System.IO.Path.Combine(path, displayFileName);
                    //输出原始文件
                    if (filePath == "" || !System.IO.File.Exists(filePath))
                    {
                        byte[] fileBytes = json.GetValue<Byte[]>("FileContent");
                        if (fileBytes != null)
                        {
                            CreateFile(fileBytes, filePath);
                        }
                    }
                    files.Add(new File() { FileID = fileId, Name = fileName, Type = fileType, IsFieldFile = true });
                    FieIdToDisplayFileName.Add(fileId, displayFileName);
                }
            }
            else if (controlKey == "F_MOB_FileServerMulti") //pc单据对应的控件类型为多选附件(文件服务)
            {
                string fieldValue = dynFile.ToString();
                JSONArray fileArray = fieldValue.IsEmpty() ? new JSONArray() : JSONArray.Parse(fieldValue);
                Files = new JSONArray();
                List<string> fileIds = new List<string>();
                foreach (Dictionary<string, object> json in fileArray)
                {
                    JSONObject fileObject = JSONObject.Parse(KDObjectConverter.SerializeObject(json));
                    Files.Add(fileObject);
                    fileIds.Add(fileObject.GetString("ServerFileName"));
                }
                var existFiles = FileServerHelper.FindByIds(this.Context, fileIds);
                if (existFiles == null || !existFiles.Any()) return;
                foreach (JSONObject fileObject in Files)
                {
                    string fileId = fileObject.GetString("ServerFileName");
                    string fileName = fileObject.GetString("FileName");
                    var file = existFiles.Find(item => item.ID == fileId);
                    if (file == null) continue;
                    string fileType = file.suffix;
                    files.Add(new File() { FileID = fileId, Name = fileName, Type = fileType, IsFieldFile = true });
                }
            }
            else if (controlKey == "F_MOB_FileServer" || controlKey == "F_MOB_ImageServer") //pc单据对应的控件类型为附件(文件服务)或图片(文件服务)
            {
                string fileId = dynFile.ToString(); //附件(文件服务)和图片(文件服务),实际存储的是文件服务器中的fileid
                var file = FileServerHelper.GetKDFileById(this.Context, fileId);
                if (file == null) return;
                string fileName = file.Name;
                string fileType = file.suffix;
                files.Add(new File() { FileID = fileId, Name = fileName, Type = fileType, IsFieldFile = true });
            }
            else if (controlKey == "F_MOB_ImageDatabase") //pc单据对应的控件类型为图片(数据库)库
            {
                string fileId = string.Empty; //图片(数据库),实际存储的是图片的byte数组
                string fileType = ".webp";
                Random random = new Random();
                string fileName = string.Format("{0}{1}{2}{3}{4}", DateTime.Now.ToString("yyyyMMddHHmmssfff"), this.Context.UserId,
System.Threading.Thread.CurrentThread.ManagedThreadId, random.Next(int.MaxValue), fileType);
                string filePath = System.IO.Path.Combine(path, fileName);
                //输出原始文件
                if (filePath == "" || !System.IO.File.Exists(filePath))
                {
                    byte[] fileBytes = (byte[])dynFile;
                    if (fileBytes != null)
                    {
                        CreateFile(fileBytes, filePath);
                    }
                }
                files.Add(new File() { FileID = fileId, Name = fileName, Type = fileType, IsFieldFile = true });
            }
            AccessoryData data = new AccessoryData()
            {
                FormId = _FormId,
                BillId = _InterID,
                Data = files
            };
            // 根据不同pc端字段,给移动端对应附件控件绑定附件信息
            // 可以一个pc端字段对应移动端一个附件控件
            if (controlKey == "F_MOB_FileDatabase" || controlKey == "F_MOB_FileServer")
            {
                this.View.GetControl("FFileUpload").SetValue(data.ToJsonString());
            }
            if (controlKey == "F_MOB_ImageDatabase" || controlKey == "F_MOB_ImageServer")
            {
                this.View.GetControl("FImageUpload").SetValue(data.ToJsonString());
            }
            if (controlKey == "F_MOB_FileServerMulti")
            {
                this.View.GetControl("FFileUploadMulti").SetValue(data.ToJsonString());
            }
        }
 
    /// <summary>
        /// 根据二进制文件,创建临时文件
        /// </summary>
        private void CreateFile(byte[] fileBytes, string filePath)
        {
            try
            {
                if (!System.IO.File.Exists(filePath) && fileBytes != null && fileBytes.Length > 0)
                {
                    using (System.IO.FileStream fs = new System.IO.FileStream(filePath, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.Read))
                    using (System.IO.BinaryWriter bw = new System.IO.BinaryWriter(fs))
                    {
                        bw.Write(fileBytes);
                    }
                }
            }
            catch { }
        }

步骤二:移动端单据头上传附件,并且绑定附件信息到PC端附件字段上面去

 /// <summary>
        /// 移动端上传附件至临时目录,并且绑定到PC端控件字段上面去
        /// </summary>
        /// <param name="e"></param>
        public override void AfterMobileUpload(BOS.Mobile.PlugIn.Args.MobileUploadEventArgs e)
        {
            if (e.Key.EqualsIgnoreCase("FImageUpload") || e.Key.EqualsIgnoreCase("FFileUpload") || e.Key.EqualsIgnoreCase("FFileUploadMulti"))
            {
                var pkValue = BillView.Model.GetPKValue();
                if (pkValue.IsEmptyPrimaryKey())
                {
                    // 单据不存在,需要先暂存
                    if (Draft(true, true))
                    {
                        pkValue = BillView.Model.GetPKValue();
                        this.UploadAttachFiles(e, pkValue.ToString());
                    }
                }
                else
                {
                    this.UploadAttachFiles(e, pkValue.ToString());
                }
            }
            else
            {
                base.AfterMobileUpload(e);
            }
        }
 
        /// <summary>
        /// 上传附件
        /// </summary>
        /// <param name="e"></param>
        /// <param name="pkValue">单据内码</param>
        private void UploadAttachFiles(BOS.Mobile.PlugIn.Args.MobileUploadEventArgs e, string pkValue)
        {
            // 获取文件上传的临时目录
            string tempDirPath = HttpContext.Current.Request.PhysicalApplicationPath + KeyConst.TEMPFILEPATH;
 
            // 仅附件(数据库)、多选附件(文件服务)支持上传多个文件,其他仅支持上传一个文件
            // 下面是pc端不同附件字段对应的附件上传方式,可根据业务需要来选择
            submitType = SubmitType.FileServerMulti;
            if (submitType == SubmitType.FileDatabase) //上传附件至数据库
            {
                StringBuilder sb = new StringBuilder();
                JSONArray fileArray = new JSONArray();
 
                foreach (FiledUploadEntity file in e.FileNameArray)
                {
                    if (!file.IsSuccess) continue; // 检查文件是否上传成功
                    var filePath = string.Empty;
                    // 检查文件是否存在
                    if (file.isNewFile)
                    {
                        // 新上传的文件,用控件提供的临时文件名查找文件
                        filePath = System.IO.Path.Combine(tempDirPath, file.FileName);
                        if (!System.IO.File.Exists(filePath)) continue;
                    }
                    else
                    {
                        // 已有的文件,用BindValue方法中动态提供的displayFileName查找文件
                        string displayFileName = FieIdToDisplayFileName[file.FileId];
                        filePath = System.IO.Path.Combine(tempDirPath, displayFileName);
                        if (!System.IO.File.Exists(filePath)) continue;
                    }
                    JSONObject fileObject = new JSONObject();
                    var dataBuff = System.IO.File.ReadAllBytes(filePath);
                    // 新上传的文件需生成FileId,已有的文件用现有的FileId
                    string fileName = file.isNewFile ? Guid.NewGuid().ToString() + " " + file.OldName : file.FileId + " " + 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;
                this.SaveFilesToBillInfo(pkValue, SerializatonUtil.SerializeToBase64(fileArray));
                sb.AppendLine();
                sb.AppendLine("上传成功");
                this.Model.SetValue("FFileLog", sb.ToString());
            }
            else if (submitType == SubmitType.FileServerMulti) //多选附件上传至文件服务器
            {
                StringBuilder sb = new StringBuilder();
                JSONArray successFiles = new JSONArray();

掌上报销单据头附件二开方案

【应用场景】客户在PC端单据头增加了附件字段,需要在掌上报销单据头也额外增加相关功能【案例演示】PC端费用报销与掌上报销单据头与单据体...
点击下载文档文档为doc格式

声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。如若本站内容侵犯了原著者的合法权益,可联系本站删除。

已经是第一篇
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息
QQ群
  • 答案:my7c点击这里加入QQ群
支持邮箱
微信
  • 微信