该段代码定义了一个名为`AuditsOperationPlugin`的类,该类继承自`AbstractOperationServicePlugIn`,主要用于处理与审计操作相关的插件功能。主要功能包括从文件服务器(确保其正常运行,并与亚马逊服务器测试成功)获取附件,并将其下载到本地。通过调用`GetFileServerUrl`方法获取文件服务器地址,利用此地址构建下载链接,通过`getFileByUrl`方法将指定附件从文件服务器下载到本地指定的临时文件夹中。同时,在处理开始阶段,还展示了如何通过OQL(对象查询语言)查询特定单据的附件信息,并为每个附件构建本地下载路径。过程中进行了异常处理,以确保文件下载的成功及错误的正确抛出。
前提: 确保文件服务器正常使用, 经实战,文件服务器和亚马逊服务器都已成功.代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Kingdee.BOS.Core.Permission;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.Operation;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Bill.PlugIn;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Core.Validation;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using Kingdee.BOS.JSON;
using Kingdee.BOS.Core;
using Kingdee.BOS;
using System.IO;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Core.SqlBuilder;
using Kingdee.BOS.Core.Attachment;
using Kingdee.BOS.Core.Metadata.FieldElement;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.Core.List;
using Kingdee.BOS.FileServer.Core;
using Kingdee.BOS.FileServer.Core.Object;
using Kingdee.BOS.FileServer.ProxyService;
using Kingdee.BOS.KDThread;
using System.ComponentModel;
using Kingdee.BOS.ServiceHelper.FileServer;
using Kingdee.BOS.Core.Metadata.FormElement;
using Kingdee.BOS.Business.Bill.Operation.Business;
using System.Threading.Tasks;
using System.Net;
using Newtonsoft.Json.Linq;
namespace CheckoutBills.AuditsOperationServer.Plugin
{
public class AuditsOperationPlugin : AbstractOperationServicePlugIn
{
//获取文件服务器地址
private string GetFileServerUrl()
{
return BusinessDataServiceHelper.GetFileServerUrl(this.Context);
}
///
///
///
/// 附件ID
///
private string GetFileByServerLocalPath(string fieldId,string attachmentName)
{
try
{
string url = GetFileServerUrl();// 获取文件服务器地址
if (url.IsNullOrEmptyOrWhiteSpace())
{
throw new KDCancelException("该文件需要从文件服务器下载,但是系统没有提供文件服务器配置信息。");
}
if (!url.EndsWith("/"))
{
url += "/";
}
string dbIdSyr = this.Context.DBId;//DBId
string userToken = this.Context.UserToken;//获取token
// 调用文件服务的下载文件服务,生成一个url资源,用户点击此URL时时,可以下载文件
string fileurl = string.Format("{0}download.aspx?fileId={1}&dbId={2}&t={3}&token={4}", url, fieldId, dbIdSyr, DateTime.Now.Ticks, userToken);
string testPath = KeyConst.TEMPFILEPATH;
testPath = HttpContext.Current.Server.MapPath(testPath);
// 获取或创建临时目录
string path = HttpContext.Current.Server.MapPath(KeyConst.TEMPFILEPATH);
//不存在则创建文件目录
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
// 生成一个临时文件名
string fileLocalPath = Path.Combine(path, attachmentName);
if (File.Exists(fileLocalPath))//如果文件存在则删除
{
File.Delete(fileLocalPath);
}
fileLocalPath = getFileByUrl(fileLocalPath, fileurl);//下载文件至本地
return fileLocalPath;//返回下载至本地的附件路径
}
catch(Exception ex)
{
throw new KDCancelException("获取检验单文档出错,请重新审核!");
}
}
///
/// 操作开始前功能处理
///
///
public override void BeginOperationTransaction(BeginOperationTransactionArgs e)
{
try
{
JObject jsonObject = new JObject();
//这里只演示操作一张单据, 如果有多张单据请遍历
DynamicObject o = e.DataEntitys[0] as DynamicObject;
string billsStr = o["Id"] + "";//得到单据内码
OQLFilter ofilter = OQLFilter.CreateHeadEntityFilter(string.Format("FINTERID = {0}", billsStr)); // Convert.ToInt64(e.Ids[i])
//得到单据里面附件对象集合
DynamicObject[] attachmentObjs = BusinessDataServiceHelper.Load(this.Context, "BOS_Attachment", null, ofilter);
string fileLocalPathOne = string.Empty;
foreach (DynamicObject attObj in attachmentObjs)
{
string createMenId = attObj["CreateMen_Id"] + "";//检验单文档上传人ID
createMenId = CommonUtil.getBase64String(createMenId);//检验单文档上传人ID 进行UTF-8编码 Base64加密
jsonObject.Add("userId", createMenId);//上传人的用户ID
string attachmentName = attObj["AttachmentName"] + "";//检验报告文件名,带后缀名
string fileIdStr = attObj["FileId"] + "";//文件ID:0e6737788b084b229e808230b183b6ce
fileLocalPathOne = GetFileByServerLocalPath(fileIdStr, attachmentName);//根据文件服务器中附件名称,或者叫附件ID获取附件
Console.WriteLine("****************下载至本地路径: fileLocalPathOne=" + fileLocalPathOne);
}
}
catch (KDException ex)
{
e.CancelOperation = true;
e.CancelFormService = true;
throw new KDCancelException("内部错误!");
}
}
///
/// 获取文件服务器或者亚马逊服务器中的文件
///
///
private string getFileByUrl(string localhostPath, string getFileUrl)
{
FileStream writeStream; // 写入本地文件流对象
long startPosition = 0; // 上次下载的文件起始位置
if (File.Exists(localhostPath))
{
writeStream = File.OpenWrite(localhostPath); // 存在则打开要下载的文件
startPosition = writeStream.Length; // 获取已经下载的长度
writeStream.Seek(startPosition, SeekOrigin.Current); // 本地文件写入位置定位
}
else
{
writeStream = new FileStream(localhostPath, FileMode.Create);// 文件不保存创建一个文件
startPosition = 0;
}
try
{
HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(getFileUrl);// 打开网络连接
if (startPosition > 0)
{
myRequest.AddRange((int)startPosition);// 设置Range值,与上面的writeStream.Seek用意相同,是为了定义远程文件读取位置
}
Stream readStream = myRequest.GetResponse().GetResponseStream();// 向服务器请求,获得服务器的回应数据流
byte[] btArray = new byte[1024];// 定义一个字节数据,用来向readStream读取内容和向writeStream写入内容
int contentSize = readStream.Read(btArray, 0, btArray.Length);// 向远程文件读第一次
while (contentSize > 0)// 如果读取长度大于零则继续读
{
writeStream.Write(btArray, 0, contentSize);// 写入本地文件
contentSize = readStream.Read(btArray, 0, btArray.Length);// 继续向远程文件读取
}
//关闭流
writeStream.Close();
readStream.Close();
return localhostPath;//返回true下载成功
}catch(Exception e)
{
writeStream.Close();
return string.Empty; //返回false下载失败
}
}
}
}
推荐阅读