using Kingdee.BOS.Core.DynamicForm.PlugIn; using Kingdee.BOS.Core.DynamicForm.PlugIn.Args; using Kingdee.BOS.JSON; using Kingdee.BOS.Util; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using Kingdee.BOS.WebApi.FormService; using System.Web; using Kingdee.BOS.Core; using Kingdee.BOS.Orm.DataEntity; using System.IO; using OpenCvSharp.Extensions; using OpenCvSharp; using Spire.Pdf.Fields; using Spire.Pdf; using System.Drawing.Imaging; using System.Drawing; using Kingdee.BOS; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Kingdee.BOS.ServiceHelper; using OpenCvSharp.Aruco; using Kingdee.BOS.Core.DynamicForm.PlugIn.ControlModel; namespace GZ.LJY000.PiLot.SAL_OUTSTOCK.UploadExtension { [HotUpdate, Description("上传附件界面")] public class BillEventPlugInEx : AbstractDynamicFormPlugIn { private string FormId = ""; private bool IsDoUploaded = false; private const string detector_prototxt_path = "detect.prototxt"; private const string detector_caffe_model_path = "detect.caffemodel"; private const string prototxt_path = "sr.prototxt"; private const string caffe_model_path = "sr.caffemodel"; private WeChatQRCode _wechatQrcode; public override void OnInitialize(InitializeEventArgs e) { base.OnInitialize(e); //FormId = e.Paramter.FormId; _wechatQrcode = weChatQRCodeInit(); } public override void ButtonClick(ButtonClickEventArgs e) { base.ButtonClick(e); if (!fileUploaded) { this.View.ShowErrMessage("文件未加载完毕!"); return; } if (e.Key.EndsWith("FDoUpLoad", StringComparison.OrdinalIgnoreCase)) { DoUpLoad(); } } private WeChatQRCode weChatQRCodeInit() { var modelPath = HttpContext.Current.Request.PhysicalApplicationPath + @"/Bin/opencv_3rdparty-wechat_qrcode/"; return WeChatQRCode.Create(modelPath + detector_prototxt_path, modelPath + detector_caffe_model_path, modelPath + prototxt_path, modelPath + caffe_model_path); } /// /// 预设图片切割区域,提高识别精度 /// /// /// /// private List GetRects(int srcWidth, int srcHeight) { List rects = new List(); #region 按图片的1/4进行切割(泛用性) var width = srcWidth / 2; var height = srcHeight / 2; var x = width * 1; var y = 0; rects.Add(new Rect(x, y, width, height)); #endregion #region 按1/9切割(泛用性) width = srcWidth / 3; height = srcHeight / 3; x = width * 2; y = 0; rects.Add(new Rect(x, y, width, height)); #endregion #region 按1/60切割(基本属于定制位置) width = srcWidth / 10; height = srcHeight / 6; x = width * 7; y = 0; width = width * 2; rects.Add(new Rect(x, y, width, height)); #endregion return rects; } /// /// 使用微信扫码开源识别 /// /// 需要扫描的图片 /// private AnalyzeResult WeChatQRCodeRectRegion(Mat src) { _wechatQrcode.DetectAndDecode(src, out var rects, out var texts); if (texts != null && texts.Length > 0) { return new AnalyzeResult { name = texts[0] }; } var rescts = GetRects(src.Width, src.Height); foreach (var rect in rescts) { using (Mat roi = new Mat(src, rect)) { _wechatQrcode.DetectAndDecode(roi, out rects, out texts); if (texts != null && texts.Length > 0) { return new AnalyzeResult { name = texts[0] }; } } } return null; } /// /// /// private void DoUpLoad() { var entity = this.View.Model.BillBusinessInfo.GetEntryEntity("FEntity"); var rows = this.View.Model.GetEntityDataObject(entity); if (rows != null && rows.Any()) { var path = HttpContext.Current.Request.PhysicalApplicationPath + @"/FileUpLoadServices/UploadFiles/"; var grid = this.View.GetControl("FEntity"); var index = 0; foreach (var row in rows) { var isSucceed = bool.Parse(row["FisSucceed"].ToString()); if (isSucceed) { index++; continue; } var fileName = row["FFileName"].ToString(); var serverFileName = row["FServerFileName"].ToString(); var fileSuffix = row["FFileSuffix"].ToString(); var fileBytesLength = row["FFileBytesLength"].Long2Int(); AnalyzeResult resData = null; //文件地址 var fullName = path + serverFileName; if (fileSuffix.ToUpper().Equals(".PDF")) { // 创建 PdfDocument 类的实例 using (PdfDocument document = new PdfDocument()) { // 加载 PDF 文档 document.LoadFromFile(fullName); // 将页面转换为图片 using (Image image = document.SaveAsImage(0, 200, 200)) { // 创建流来保存图片数据 using (MemoryStream stream = new MemoryStream()) { // 将图片以 PNG 格式保存到流中 image.Save(stream, ImageFormat.Png); stream.Position = 0; using (Mat src = BitmapConverter.ToMat(new Bitmap(image))) { resData = WeChatQRCodeRectRegion(src); } } } } } else if (fileSuffix.ToUpper().Equals(".JPG")) { using (Mat src = new Mat(fullName)) { resData = WeChatQRCodeRectRegion(src); } } if (resData != null) { var isSuccess = false; var resMsg = string.Empty; row["FBillNo"] = resData.name; if (!resData.name.IsNullOrEmptyOrWhiteSpace()) { var base64 = FileToBase64String(fullName); var resultJson = DoAttachmentUpload("SAL_OUTSTOCK", fileName, resData.name, fileBytesLength, fileSuffix, base64); if (resultJson != null) { var result = JsonConvert.DeserializeObject(resultJson); //var result = resultJson as JObject; var responseData = result["Result"]["ResponseStatus"]; isSuccess = responseData["IsSuccess"].Value(); resMsg = JsonConvert.SerializeObject(responseData); } else { resMsg = "识别单号找不到对应销售出库单!"; } } if (isSuccess) { row["FisSucceed"] = true; row["FResultMsg"] = "上传完毕"; grid.SetForecolor("FFileName", "#00994C", index); } else { if (resMsg.IsNullOrEmpty()) resMsg = "识别失败!"; row["FisSucceed"] = false; row["FResultMsg"] = resMsg; grid.SetForecolor("FFileName", "#FF3300", index); } } else { row["FisSucceed"] = false; row["FResultMsg"] = "未知错误导致识别失败!"; grid.SetForecolor("FFileName", "#FF3300", index); } index++; } //fileUploaded = false; this.View.UpdateView("FEntity"); } } /// /// 文件转base64 /// /// base64字符串 public string FileToBase64String(string fullName) { string base64Str = ""; try { var fileBytes = File.ReadAllBytes(fullName); return Convert.ToBase64String(fileBytes); } catch (Exception ex) { Console.Write(ex.Message); Console.ReadLine(); return base64Str; } finally { //fsForRead.Close(); } } /// /// 识别二维码 /// /// /// /// /// private static AnalyzeResult DecodeQRCodes(Mat src, Rect region, bool isReturn) { AnalyzeResult analyzeResult = null; // 裁剪指定区域 using (Mat roi = new Mat(src, region)) { // 转为灰度图像 using (Mat gray = new Mat()) { Cv2.CvtColor(roi, gray, ColorConversionCodes.BGR2GRAY); // 二值化处理 using (Mat binary = new Mat()) { Cv2.Threshold(gray, binary, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu); //二维码识别 using (QRCodeDetector qRCodeDetector = new QRCodeDetector()) { Point2f[] points; var hasQRCode = qRCodeDetector.DetectMulti(binary, out points); if (hasQRCode) { qRCodeDetector.DecodeMulti(binary, points, out string[] qrCodeTexts); analyzeResult = new AnalyzeResult(); analyzeResult.name = qrCodeTexts[0]; analyzeResult.points = points; } else { if (isReturn) return null; var srcWidth = roi.Width; var srcHeight = roi.Height; int x = srcWidth / 2; int y = 0; int width = srcWidth / 2; int height = srcHeight / 2; var newRegion = new Rect(x, y, width, height); analyzeResult = DecodeQRCodes(roi, newRegion, true); } } } } } return analyzeResult; } public class AnalyzeResult { public string fileName { get; set; } public string name { get; set; } public Point2f[] points { get; set; } } /// /// /// /// /// /// /// /// /// /// private string DoAttachmentUpload(string formId, string fileName, string billNo, int fileBytesLength, string fileSuffix, string base64) { if (this.Context.DBId.Equals("6735f10547df64")) billNo = "ZHBR-XSCKD240911002"; var InterId = 0L; var formBillNo = ""; var sqlL = $@"/*dialect*/ SELECT t0.FBILLNO,t0.FID,t0e.FENTRYID,t0e.FSEQ,t0e_lk.FSTABLENAME,t0e_lk.FSBILLID FROM T_SAL_OUTSTOCK t0 INNER JOIN T_SAL_OUTSTOCKENTRY t0e on t0.FID = t0e.FID INNER JOIN T_SAL_OUTSTOCKENTRY_LK t0e_lk on t0e_lk.FENTRYID = t0e.FENTRYID AND t0e_lk.FSTABLENAME = 'T_SAL_DELIVERYNOTICEENTRY' INNER JOIN T_SAL_DELIVERYNOTICE t1 on t1.FID = t0e_lk.FSBILLID WHERE t1.FBILLNO = '{billNo}' "; var data = DBServiceHelper.ExecuteDynamicObject(this.Context, sqlL); if (data != null && data.Any()) { InterId = data[0]["FID"].Long2Int(); formBillNo = data[0]["FBILLNO"].ToString(); } else { return null; } var fileSql = @"/*dialect*/ SELECT * FROM T_BAS_FILESERVERINFO WHERE FUSED = 1 ORDER BY FENABLE DESC"; var fileServerInfo = DBServiceHelper.ExecuteDynamicObject(this.Context, fileSql); if (fileServerInfo != null && fileServerInfo.Count > 0) { string jsonData = $@" {{ ""FileName"": ""{fileName}"", ""FEntryKey"": "" "", ""FormId"": ""{formId}"", ""IsLast"": true, ""InterId"": {InterId}, ""BillNO"": ""{formBillNo}"", ""AliasFileName"": """", ""SendByte"": ""{base64}"" }} "; var resultJson = WebApiServiceCall.AttachmentUpload(this.Context, jsonData); return JsonConvert.SerializeObject(resultJson); } else { var jsonData = $@" {{ ""Model"": {{ ""FAttachmentName"": ""{fileName}"", ""FBillType"": ""{formId}"", ""FInterID"": ""{InterId}"", ""FBillNo"": ""{formBillNo}"", ""FAttachmentSize"": {(Math.Round((decimal)fileBytesLength / 1024, 2))}, ""FAttachment"":""{base64}"", ""FFILESTORAGE"":0, ""FExtName"": ""{fileSuffix}"", ""FEntryinterId"": ""-1"", ""FEntrykey"": "" "", ""FaliasFileName"": ""{fileName}"", ""FCreateMen"": {{ ""FUserID"": ""{this.Context.UserId}"" }}, ""FCreateTime"":""{DateTime.Now:F}"" }} }} "; var resultJson = WebApiServiceCall.Save(this.Context, "BOS_Attachment", jsonData); return JsonConvert.SerializeObject(resultJson); } } //K3CloudApi clienter = null; bool fileUploaded = false; public override void CustomEvents(CustomEventsArgs e) { base.CustomEvents(e); if (e.EventName.ToUpper().Equals("FILECHANGED") && e.Key.ToUpper().Equals("FFILEUPDATECLIENT")) { fileUploaded = false; var postData = KDObjectConverter.DeserializeObject(e.EventArgs); if (postData != null) { var uploadInfo = new JSONArray(postData["NewValue"].ToString()); var entity = this.View.Model.BillBusinessInfo.GetEntryEntity("FEntity"); var rows = this.View.Model.GetEntityDataObject(entity); rows.Clear(); if (uploadInfo.Count > 0) { foreach (Dictionary fileInfo in uploadInfo) { var row = new DynamicObject(entity.DynamicObjectType); var fileName = fileInfo["FileName"].ToString(); var suffix = Path.GetExtension(fileName); if (suffix.ToUpper().Equals(".PDF") || suffix.ToUpper().Equals(".JPG")) { row["FFileName"] = fileName; row["FServerFileName"] = fileInfo["ServerFileName"]; row["FFileSuffix"] = suffix; row["FFileBytesLength"] = fileInfo["FileBytesLength"]; rows.Add(row); } } this.View.UpdateView("FEntity"); fileUploaded = true; } } return; } } } }