jeremy 9 сар өмнө
parent
commit
3540a7cbf7

BIN
Depends/ReportGenerator.dll


+ 4 - 0
ReportGenerator/ReportWordDocumentManager.cs

@@ -330,6 +330,10 @@ namespace ReportService
                 height = 3000;
 
             section.PageSetup.PageSize = new Syncfusion.Drawing.SizeF(width, height);
+            if (width > height)
+            {
+                section.PageSetup.Orientation = PageOrientation.Landscape;
+            }
             section.PageSetup.Margins = new MarginsF((float)pagePadding.Left,
                 (float)pagePadding.Top, (float)pagePadding.Right,
                 (float)pagePadding.Bottom);

+ 508 - 34
ReportService/Service/ReportService.RemoteUltrasound.cs

@@ -11,6 +11,8 @@ using WingInterfaceLibrary.Interface;
 using WingServerCommon.Log;
 using SkiaSharp;
 using Newtonsoft.Json.Linq;
+using WingInterfaceLibrary.Enum.VitalEnum;
+using Newtonsoft.Json;
 
 namespace ReportService.Service
 {
@@ -140,14 +142,482 @@ namespace ReportService.Service
             return reportInfo;
         }
 
-        
+        /// <summary>
+        /// 读取数据并生成报告所需的json
+        /// </summary>
+        private async Task<List<dynamic>> ReadDataFromExam(string examData, string userCode, WingInterfaceLibrary.DTO.Vital.ElectrocardiogramRecord examRecord)
+        {
+
+            var newDataJsonDynamicList = new List<dynamic>();
+            try
+            {
+
+                var userInfo = await _vitalUserDBService.GetUserDetailAsync(new WingInterfaceLibrary.Request.DBVitalRequest.GetUserDBRequest
+                {
+                    Code = userCode
+                });
+                //当前用户的签名
+                var doctorSign = userInfo.Signature;
+                var examDoctor = userInfo.Signature;//userInfo.UserName;//todo
+
+                var orgName = examRecord?.OrganizationName ?? string.Empty;
+                var examTime = UTCToBeijing(examRecord.ExamTime).ToString("yyyy-MM-dd HH:mm:ss.fff");
+
+                var patientName = examRecord?.PatientName ?? string.Empty;
+                var physicalExamNumber = examRecord?.PhysicalExamNumber ?? string.Empty;
+                var cardNo = examRecord?.CardNo ?? string.Empty;
+                var sex = "";
+                if (examRecord.PatientGender == GenderEnum.Female)
+                {
+                    sex = "女";
+                }
+                else if (examRecord.PatientGender == GenderEnum.Male)
+                {
+                    sex = "男";
+                }
+                else if (examRecord.PatientGender == GenderEnum.Unspecified)
+                {
+                    sex = "未说明的性别";
+                }
+                else
+                {
+                    sex = "未知的性别";
+                }
+                var age = "";
+                if (examRecord?.Birthday > Convert.ToDateTime("1900-1-1"))
+                {
+                    age = CalculateAge(examRecord.Birthday).ToString() ?? string.Empty;
+                }
+                // var birthday = "";
+                // if (examRecord?.Birthday > Convert.ToDateTime("1900-1-1"))
+                // {
+                //     birthday = examRecord?.Birthday.ToUniversalTime().ToString("yyyy-MM-dd") ?? "";
+                // }
+                // var phone = examRecord?.Phone ?? string.Empty;
+                // var adress = examRecord?.PatientAddress ?? string.Empty;
+
+
+                var index = "";
+                var HR = "";
+                var PR = "";
+                var PDur = "";
+                var QRSDur = "";
+                var TDur = "";
+                var QTDur = "";
+                var QTCDur = "";
+                var QT_QTC_Dur = "";
+                var PAxis = "";
+                var QRSAxis = "";
+                var TAxis = "";
+                var P_QRS_T_Axis = "";
+                var Rv5_Sv1_1 = "";
+                var Rv5_Sv1_2 = "";
+                var ASSESS12 = "";
+                var ecgImage = "";
+                if (!string.IsNullOrEmpty(examData))
+                {
+                    JObject json = JObject.Parse(examData);
+                    if (json == null)
+                    {
+                        return newDataJsonDynamicList;
+                    }
+
+                    var Analyse12 = "";
+                    if (json.ContainsKey("Analyse12"))
+                    {
+                        Analyse12 = json["Analyse12"].ToString();
+                    }
+                    if (json.ContainsKey("ASSESS12"))
+                    {
+                        ASSESS12 = json["ASSESS12"].ToString();
+                    }
+                    var ECG12 = "";
+                    if (json.ContainsKey("ECG12"))
+                    {
+                        ECG12 = json["ECG12"].ToString();
+                    }
+
+                    var baselineFiltering = "";
+                    var eMGFiltering = "";
+                    var ac = "";
+                    var powerLineFiltering = "";
+                    var paperSpeed = "";
+                    var gain = "";
+                    if (json.ContainsKey("BaselineFiltering"))
+                    {
+                        baselineFiltering = json["BaselineFiltering"].ToString();
+                    }
+                    if (json.ContainsKey("EMGFiltering"))
+                    {
+                        eMGFiltering = json["EMGFiltering"].ToString();
+                    }
+                    if (json.ContainsKey("AC"))
+                    {
+                        ac = json["AC"].ToString();
+                    }
+                    if (json.ContainsKey("PowerLineFiltering"))
+                    {
+                        powerLineFiltering = json["PowerLineFiltering"].ToString();
+                    }
+                    if (json.ContainsKey("PaperSpeed"))
+                    {
+                        paperSpeed = json["PaperSpeed"].ToString();
+                    }
+                    if (json.ContainsKey("Gain"))
+                    {
+                        gain = json["Gain"].ToString();
+                    }
+                    var text = baselineFiltering + " " + eMGFiltering + " " + ac + " " + powerLineFiltering + " " + paperSpeed + " " + gain;
+                    ecgImage = await GetImageAddTextAsync(ECG12, text);
+                    if (!string.IsNullOrEmpty(Analyse12))
+                    {
+                        JObject jsonAnalyse12 = JObject.Parse(Analyse12);
+                        if (jsonAnalyse12 != null)
+                        {
+                            if (string.IsNullOrWhiteSpace(doctorSign))
+                            {
+                                if (jsonAnalyse12.ContainsKey("DiagnosticEleSignature") && !string.IsNullOrWhiteSpace(jsonAnalyse12["DiagnosticEleSignature"].ToString()))
+                                {
+                                    doctorSign = jsonAnalyse12["DiagnosticEleSignature"].ToString();
+                                }
+                            }
+                            if (string.IsNullOrWhiteSpace(examDoctor))
+                            {
+                                if (jsonAnalyse12.ContainsKey("ReviewEleSignature") && !string.IsNullOrWhiteSpace(jsonAnalyse12["ReviewEleSignature"].ToString()))
+                                {
+                                    examDoctor = jsonAnalyse12["ReviewEleSignature"].ToString();
+                                }
+                            }
+                            if (jsonAnalyse12.ContainsKey("Rv5_Sv1_1"))
+                            {
+                                Rv5_Sv1_1 = jsonAnalyse12["Rv5_Sv1_1"].ToString() + " mv";
+                            }
+                            if (jsonAnalyse12.ContainsKey("Rv5_Sv1_2"))
+                            {
+                                Rv5_Sv1_2 = jsonAnalyse12["Rv5_Sv1_2"].ToString().Trim() + " mv";
+                            }
+                            if (jsonAnalyse12.ContainsKey("QRSAxis"))
+                            {
+                                QRSAxis = jsonAnalyse12["QRSAxis"].ToString() + " deg";
+                            }
+                            if (jsonAnalyse12.ContainsKey("TAxis"))
+                            {
+                                TAxis = jsonAnalyse12["TAxis"].ToString() + " deg";
+                            }
+                            if (jsonAnalyse12.ContainsKey("P_QRS_T_Axis"))
+                            {
+                                P_QRS_T_Axis = jsonAnalyse12["P_QRS_T_Axis"].ToString() + " deg";
+                            }
+                            if (jsonAnalyse12.ContainsKey("QTDur"))
+                            {
+                                QTDur = jsonAnalyse12["QTDur"].ToString() + " ms";
+                            }
+                            if (jsonAnalyse12.ContainsKey("QTCDur"))
+                            {
+                                QTCDur = jsonAnalyse12["QTCDur"].ToString() + " ms";
+                            }
+                            if (jsonAnalyse12.ContainsKey("QT_QTC_Dur"))
+                            {
+                                QT_QTC_Dur = jsonAnalyse12["QT_QTC_Dur"].ToString() + " ms";
+                            }
+                            if (jsonAnalyse12.ContainsKey("PAxis"))
+                            {
+                                PAxis = jsonAnalyse12["PAxis"].ToString() + " deg";
+                            }
+                            if (jsonAnalyse12.ContainsKey("QRSDur"))
+                            {
+                                QRSDur = jsonAnalyse12["QRSDur"].ToString() + " ms";
+                            }
+                            if (jsonAnalyse12.ContainsKey("TDur"))
+                            {
+                                TDur = jsonAnalyse12["TDur"].ToString() + " ms";
+                            }
+                            if (jsonAnalyse12.ContainsKey("HR"))
+                            {
+                                HR = jsonAnalyse12["HR"].ToString() + " bpm";
+                            }
+                            if (jsonAnalyse12.ContainsKey("PR"))
+                            {
+                                PR = jsonAnalyse12["PR"].ToString() + " ms";
+                            }
+                            if (jsonAnalyse12.ContainsKey("PDur"))
+                            {
+                                PDur = jsonAnalyse12["PDur"].ToString() + " ms";
+                            }
+                            if (jsonAnalyse12.ContainsKey("index"))
+                            {
+                                index = jsonAnalyse12["index"].ToString();
+                            }
+                        }
+                    }
+                }
+
+                #region 页脚
+                dynamic dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "415df52f-3fef-46c5-a39f-c3e3090e79f2";
+                dynamicObj.Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
+                dynamicObj.Name = "ReportTime";
+                dynamicObj.TagId = "4abbaa61-a91d-4399-a3f4-df29117d2d59";
+                newDataJsonDynamicList.Add(dynamicObj);
+
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "779493a0-8900-4503-b77b-b65913842b8c1";
+                dynamicObj.Value = examDoctor;
+                dynamicObj.Name = "ReportPhysician";
+                dynamicObj.TagId = "5abbaa61-a91d-4399-a3f4-df29117d2d59";
+                newDataJsonDynamicList.Add(dynamicObj);
+
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "779493a0-8900-4503-b77b-b65913842b8c";
+                dynamicObj.Value = doctorSign;
+                dynamicObj.Name = "DigitalSignature";
+                dynamicObj.TagId = "53545af1-59b7-41a8-9bd5-bdba1aaf9891";
+                newDataJsonDynamicList.Add(dynamicObj);
+                #endregion
+
+                #region 抬头
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "1790e450-19a6-4000-8895-3dda6a43aef9";
+                dynamicObj.Value = orgName;
+                dynamicObj.Name = "HospitalName";
+                dynamicObj.TagId = "7abbaa61-a91d-4399-a3f4-df29117d2d59";
+                newDataJsonDynamicList.Add(dynamicObj);
+                #endregion
+
+                #region 病人信息
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "fced54ee-f02b-49e7-b443-c217e37287ab";
+                dynamicObj.Value = patientName;
+                dynamicObj.Name = "PatientName";
+                dynamicObj.TagId = "91bbaa61-a91d-4399-a3f4-df29117d2d59";
+                newDataJsonDynamicList.Add(dynamicObj);
+
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "81d2aa8b-569f-40ce-8e9c-8e5f3c18eaeb";
+                dynamicObj.Value = sex;
+                dynamicObj.Name = "PatientGender";
+                dynamicObj.TagId = "93bbaa61-a91d-4399-a3f4-df29117d2d59";
+                newDataJsonDynamicList.Add(dynamicObj);
+
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "2a112884-5ea2-478a-a81b-01c20391c75c";
+                dynamicObj.Value = age;
+                dynamicObj.Name = "PatientAge";
+                dynamicObj.TagId = "92bbaa61-a91d-4399-a3f4-df29117d2d59";
+                newDataJsonDynamicList.Add(dynamicObj);
+
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "10d37b65-d37d-47b1-83bb-e320080d503d";
+                dynamicObj.Value = physicalExamNumber;
+                dynamicObj.Name = "PhysicalExamNumber";
+                dynamicObj.TagId = "A1843C2E-B60A-483F-A5F0-B26F475A362w";
+                newDataJsonDynamicList.Add(dynamicObj);
+
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "683d5247-8e06-4227-aded-10032b754c4b";
+                dynamicObj.Value = examTime;
+                dynamicObj.Name = "PatientExamDate";
+                dynamicObj.TagId = "95bbaa61-a91d-4399-a3f4-df29117d2d59";
+                newDataJsonDynamicList.Add(dynamicObj);
+                #endregion
+
+                #region 图像处理
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "be12187d-c1d1-48dd-b56d-13c7cf897542";
+                dynamicObj.Value = new List<string>() { ecgImage };
+                dynamicObj.Name = "PatientECGImage";
+                dynamicObj.TagId = "A1843C2E-B60A-483F-A5F0-B26F475A361z";
+                newDataJsonDynamicList.Add(dynamicObj);
+                #endregion
+
+                #region 心电数据
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "a3c110ca-8081-41df-a0aa-9604070ce7dc";
+                dynamicObj.Value = HR;
+                dynamicObj.Name = "HR";
+                dynamicObj.TagId = "33D46E3F-A089-4B0A-8D1D-F4C7556BD62D";
+                newDataJsonDynamicList.Add(dynamicObj);
+
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "4a52b32f-876a-4365-b590-00d88d9cc36d";
+                dynamicObj.Value = TAxis;
+                dynamicObj.Name = "PatientTAxis";
+                dynamicObj.TagId = "A1843C2E-B60A-483F-A5F0-B26F475A362h";
+                newDataJsonDynamicList.Add(dynamicObj);
+
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "25c1d36b-1550-4fee-9c40-3b134feb26fb";
+                dynamicObj.Value = PAxis;
+                dynamicObj.Name = "PatientPAxis";
+                dynamicObj.TagId = "A1843C2E-B60A-483F-A5F0-B26F475A362f";
+                newDataJsonDynamicList.Add(dynamicObj);
+
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "a871072f-810e-4d57-ad9d-244fa21e47e2";
+                dynamicObj.Value = QRSAxis;
+                dynamicObj.Name = "PatientQRSAxis";
+                dynamicObj.TagId = "A1843C2E-B60A-483F-A5F0-B26F475A362g";
+                newDataJsonDynamicList.Add(dynamicObj);
+
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "9616f7d6-4c89-4b8a-8ee3-0675b829344e";
+                dynamicObj.Value = PR;
+                dynamicObj.Name = "PatientPRInterval";
+                dynamicObj.TagId = "A1843C2E-B60A-483F-A5F0-B26F475A362j";
+                newDataJsonDynamicList.Add(dynamicObj);
+
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "13f30eaf-e7b1-440c-a03d-0454b01120b1";
+                dynamicObj.Value = QT_QTC_Dur;
+                dynamicObj.Name = "PatientQTQTCInterval";
+                dynamicObj.TagId = "A1843C2E-B60A-483F-A5F0-B26F475A362l";
+                newDataJsonDynamicList.Add(dynamicObj);
+
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "75f69125-41eb-4067-bd7c-8942478c691f";
+                dynamicObj.Value = Rv5_Sv1_1;
+                dynamicObj.Name = "PatientRV5SV";
+                dynamicObj.TagId = "A1843C2E-B60A-483F-A5F0-B26F475A362m";
+                newDataJsonDynamicList.Add(dynamicObj);
+
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "996beabe-401c-44a9-8bd1-69b2905be9a2";
+                dynamicObj.Value = QRSDur;
+                dynamicObj.Name = "PatientQRSDuration";
+                dynamicObj.TagId = "A1843C2E-B60A-483F-A5F0-B26F475A362k";
+                newDataJsonDynamicList.Add(dynamicObj);
+
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "A1843C2E-B60A-483F-A5F0-B26F475A362n";
+                dynamicObj.Value = Rv5_Sv1_2;
+                dynamicObj.Name = "PatientRV5SV1";
+                dynamicObj.TagId = "A1843C2E-B60A-483F-A5F0-B26F475A362n";
+                newDataJsonDynamicList.Add(dynamicObj);
+                #endregion
+
+                #region 诊断结果
+                dynamicObj = new System.Dynamic.ExpandoObject();
+                dynamicObj.Key = "e935734b-cdf9-4ff1-8cb6-18fb6e1dcc05";
+                dynamicObj.Value = ASSESS12;
+                dynamicObj.Name = "PatientEcgDiagnosticResult";
+                dynamicObj.TagId = "A1843C2E-B60A-483F-A5F0-B26F475A362e";
+                newDataJsonDynamicList.Add(dynamicObj);
+                #endregion
+            }
+            catch (Exception ex)
+            {
+                Logger.WriteLineError($"ElectrocardiogramService ReadDataFromExam error, examRecord: {Newtonsoft.Json.JsonConvert.SerializeObject(examRecord)}, ex:{ex}");
+            }
+            return newDataJsonDynamicList;
+        }
+
+        /// <summary>
+        /// 图像添加文字
+        /// </summary>
+        private async Task<string> GetImageAddTextAsync(string fileUrl, string text)
+        {
+            var imgUrl = "";
+            if (!string.IsNullOrEmpty(fileUrl))
+            {
+                using (HttpClient client = new HttpClient())
+                {
+                    using (HttpResponseMessage response = client.GetAsync(fileUrl).Result)
+                    {
+                        var bytes = response.Content.ReadAsByteArrayAsync().Result;
+
+                        using (var bitmap = SkiaSharp.SKBitmap.Decode(bytes))
+                        {
+                            using (SKCanvas canvas = new SKCanvas(bitmap))
+                            {
+                                // 创建一个SKPaint实例,设置文本属性
+                                using (SKPaint paint = new SKPaint())
+                                {
+                                    paint.Color = SKColors.Black; // 设置文本颜色
+                                    paint.TextSize = 16; // 设置文本大小
+
+                                    var textBounds = new SKRect();
+                                    paint.MeasureText(text, ref textBounds);
+                                    float x = bitmap.Width - textBounds.Width - 20;
+
+                                    // 绘制文本到位于(50, 50)的位置
+                                    canvas.DrawText(text, x, 20, paint);
+                                }
+                            }
+                            var _reportPreviewFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ReportPreviewTemp");
+                            if (!Directory.Exists(_reportPreviewFolder))
+                            {
+                                Directory.CreateDirectory(_reportPreviewFolder);
+                            }
+                            else
+                            {
+                                //删除过时文件
+                                var time =  DateTime.Now.AddDays(-1);
+                                DirectoryInfo theFolder = new DirectoryInfo(_reportPreviewFolder);
+                                DirectoryInfo[] dics = theFolder.GetDirectories();
+                                foreach (var item in dics)
+                                {
+                                    if (item.CreationTime < time)
+                                    {
+                                        Directory.Delete(item.FullName, true);
+                                    }
+                                }
+                                FileInfo[] fileInfo = theFolder.GetFiles();
+                                foreach (FileInfo File in fileInfo)  //遍历文件
+                                {
+                                    if (File.CreationTime < time)
+                                    {
+                                        File.Delete();
+                                    }
+                                }
+                            }
+                            DirectoryInfo reportFolder = new DirectoryInfo(_reportPreviewFolder);
+                            string fileName = $"{Guid.NewGuid().ToString("N")}";
+                            string imagePath = Path.Combine(_reportPreviewFolder, fileName) + ".jpg";
+                            using (var fileStream = new FileStream(imagePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
+                            {
+                                bitmap.Encode(fileStream, SkiaSharp.SKEncodedImageFormat.Jpeg, 100);
+                            }
+                            if (File.Exists(imagePath))
+                            {
+                                var _fileTransfer = new WingServerCommon.Interfaces.FileTransfer.FileTransferService();
+                                var dataList = await _fileTransfer.FileTransferAsync(imagePath, false, false);
+                                if (dataList == null || dataList.Count <= 0)
+                                {
+                                    Logger.WriteLineError($"Upload Files Way-2 {imagePath} Fail");
+                                    return fileUrl;
+                                }
+                                var fileToken = dataList.FirstOrDefault();
+                                if (!string.IsNullOrWhiteSpace(fileToken))
+                                {
+                                    imgUrl = fileToken;
+                                }
+                                File.Delete(imagePath);
+                            }
+                        }
+                    }
+                }
+            }
+            return imgUrl;
+        }
+
         /// <summary>
         /// 创建远程心电报告
         /// </summary>
         /// <param name="request"></param>
         /// <returns></returns>
-        private async Task<string> VitalAddEcgReportAsync(string userCode, AddReportRequest request)
+        public async Task<string> VitalAddEcgReportAsync(AddEcgReportRequest request)
         {
+            var userCode = await ValidateTokenAsync(request.Token);
+            if (string.IsNullOrWhiteSpace(request.RecordCode))
+            {
+                ThrowCustomerException(CustomerRpcCode.RecordCodeEmpty, "RecordCode empty error");
+            }
+            var reqReportTempDB = new WingInterfaceLibrary.DB.Request.GetReportTemplateDBRequest()
+            {
+                ReportTemplateCode = request.ReportTemplateCode,
+                LanguageCode = "zh-CN"
+            };
+            var reportTemplateInfo = await _reportDBService.GetReportTemplateAsync(reqReportTempDB) ?? new WingInterfaceLibrary.DTO.ReportTemplate.ReportTemplateDTO();
             var deviceCode = "";
             var patientCode = "";
             var record = await _vitalElectrocardiogramDBService.GetExamElectrocardiogramDBAsync(request.RecordCode);
@@ -157,14 +627,11 @@ namespace ReportService.Service
             }
             deviceCode = record.DeviceCode;
             patientCode = record.CardNo;
-            if (string.IsNullOrWhiteSpace(request.ReportTemplateJson))
-            {
-                ThrowCustomerException(CustomerRpcCode.ReportTemplateJsonEmpty, "ReportTemplateJson empty error");
-            }
             if (string.IsNullOrWhiteSpace(request.ReportDatasJson))
             {
                 ThrowCustomerException(CustomerRpcCode.ReportDatasJsonEmpty, "ReportDatasJson empty error");
             }
+            var reportDataList = await ReadDataFromExam(request.ReportDatasJson, userCode, record);
             var patientId = GetPatientId(request.ReportDatasJson);
             var reportId = await _reportDBService.SaveReportAsync(new SaveReportDBRequest
             {
@@ -172,19 +639,20 @@ namespace ReportService.Service
                 ReportUserCode = userCode,
                 DeviceCode = deviceCode,
                 PatientCode = patientCode,
-                ReportTemplateJson = request.ReportTemplateJson ?? "{}",
-                ReportDatasJson = request.ReportDatasJson,
+                ReportTemplateJson = reportTemplateInfo.ReportTemplateJson ?? "{}",
+                ReportDatasJson = JsonConvert.SerializeObject(reportDataList),
                 PatientId = patientId,
                 PatientName = request.PatientName,
-                ReportLabels = request.ReportLabels ?? new List<string>(),
-                PlatformLabels = request.PlatformLabels ?? new List<string>(),
-                DiagnosisLabels = request.DiagnosisLabels ?? new List<string>(),
-                ReportOrgan = request.ReportOrgan,
-                ReferralRecordCode = request.ReferralRecordCode,
-                ReportType = request.ReportType,
-                IsReferral = request.IsReferral,
+                ReportLabels = new List<string>(),
+                PlatformLabels =  new List<string>(),
+                DiagnosisLabels = new List<string>(),
+                ReportOrgan = DiagnosisOrganEnum.Null,
+                ReferralRecordCode = "",
+                ReportType = ReportTypeEnum.RemoteECG,
+                IsReferral = false,
                 ReportTemplateCode = request.ReportTemplateCode,
-                ReportMeasureDatasJson = request.ReportMeasureDatasJson
+                ReportMeasureDatasJson = "",
+                ReportExamDataJson = request.ReportDatasJson
             });
             if (string.IsNullOrEmpty(reportId))
             {
@@ -217,6 +685,7 @@ namespace ReportService.Service
             {
                 ThrowCustomerException(CustomerRpcCode.RecordCodeEmpty, "RecordCode empty error");
             }
+            Logger.WriteLineWarn($"VitalAddReportAsync true, request: {Newtonsoft.Json.JsonConvert.SerializeObject(request)}");
             var deviceCode = "";
             var patientCode = "";
             var record = new RecordInfoDTO();
@@ -231,9 +700,6 @@ namespace ReportService.Service
                     deviceCode = record.DeviceCode;
                     patientCode = record.PatientCode;
                     break;
-                case ReportTypeEnum.RemoteECG:
-                    var ecgReport = await VitalAddEcgReportAsync(userCode, request);
-                    return ecgReport;
             }
             if (string.IsNullOrWhiteSpace(request.ReportTemplateJson) && !request.DiagnosisLabels.Contains("VAid"))
             {
@@ -298,8 +764,21 @@ namespace ReportService.Service
         /// </summary>
         /// <param name="request"></param>
         /// <returns></returns>
-        private async Task<bool> VitalModifyEcgReportAsync(string userCode, ModifyReportRequest request)
+        public async Task<bool> VitalModifyEcgReportAsync(ModifyEcgReportRequest request)
         {
+            var userCode = await ValidateTokenAsync(request.Token);
+            if (string.IsNullOrWhiteSpace(request.RecordCode))
+            {
+                ThrowCustomerException(CustomerRpcCode.RecordCodeEmpty, "RecordCode empty error");
+            }
+            Logger.WriteLineWarn($"VitalModifyEcgReportAsync true, request: {Newtonsoft.Json.JsonConvert.SerializeObject(request)}");
+            
+            var reqReportTempDB = new WingInterfaceLibrary.DB.Request.GetReportTemplateDBRequest()
+            {
+                ReportTemplateCode = request.ReportTemplateCode,
+                LanguageCode = "zh-CN"
+            };
+            var reportTemplateInfo = await _reportDBService.GetReportTemplateAsync(reqReportTempDB) ?? new WingInterfaceLibrary.DTO.ReportTemplate.ReportTemplateDTO();
             var deviceCode = "";
             var patientCode = "";
             var record = await _vitalElectrocardiogramDBService.GetExamElectrocardiogramDBAsync(request.RecordCode);
@@ -315,14 +794,11 @@ namespace ReportService.Service
                 var userOrganReport = examReportList.FirstOrDefault(x => x.ReportUserCode == userCode);
                 request.ReportCode = userOrganReport?.ReportCode ?? string.Empty;
             }
-            if (string.IsNullOrWhiteSpace(request.ReportTemplateJson))
-            {
-                ThrowCustomerException(CustomerRpcCode.ReportTemplateJsonEmpty, "ReportTemplateJson empty error");
-            }
             if (string.IsNullOrWhiteSpace(request.ReportDatasJson))
             {
                 ThrowCustomerException(CustomerRpcCode.ReportDatasJsonEmpty, "ReportDatasJson empty error");
             }
+            var reportDataList = await ReadDataFromExam(request.ReportDatasJson, userCode, record);
             var saveRequest = new SaveReportDBRequest
             {
                 ReportCode = request.ReportCode,
@@ -330,17 +806,18 @@ namespace ReportService.Service
                 ReportUserCode = userCode,
                 DeviceCode = deviceCode,
                 PatientCode = patientCode,
-                ReportTemplateJson = request.ReportTemplateJson ?? "{}",
-                ReportDatasJson = request.ReportDatasJson,
+                ReportTemplateJson = reportTemplateInfo.ReportTemplateJson ?? "{}",
+                ReportDatasJson = JsonConvert.SerializeObject(reportDataList),
                 PatientId = GetPatientId(request.ReportDatasJson),
                 PatientName = request.PatientName,
-                ReportLabels = request.ReportLabels ?? new List<string>(),
-                PlatformLabels = request.PlatformLabels ?? new List<string>(),
+                ReportLabels = new List<string>(),
+                PlatformLabels = new List<string>(),
                 DiagnosisLabels = new List<string>(),
-                ReportOrgan = request.ReportOrgan,
-                ReferralRecordCode = request.ReferralRecordCode,
+                ReportOrgan = DiagnosisOrganEnum.Null,
+                ReferralRecordCode = "",
                 ReportTemplateCode = request.ReportTemplateCode,
-                ReportMeasureDatasJson = request.ReportMeasureDatasJson
+                ReportMeasureDatasJson = "",
+                ReportExamDataJson = request.ReportDatasJson
             };
             var reportId = await _reportDBService.SaveReportAsync(saveRequest);
             if (!string.IsNullOrEmpty(reportId))
@@ -409,9 +886,6 @@ namespace ReportService.Service
                     deviceCode = record.DeviceCode;
                     patientCode = record.PatientCode;
                     break;
-                 case ReportTypeEnum.RemoteECG:
-                    var ecgReport = await VitalModifyEcgReportAsync(userCode, request);
-                    return ecgReport;
             }
             var diagnosisLabels = request.DiagnosisLabels ?? new List<string>();
             if (request.ReportOrgan != DiagnosisOrganEnum.Null && !string.IsNullOrWhiteSpace(userCode))