diff --git a/AksWebBrowser.sln b/AksWebBrowser.sln new file mode 100644 index 0000000..2d69e9e --- /dev/null +++ b/AksWebBrowser.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34622.214 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AKS.EnterpriseLibrary.WebBrowser", "CPF_Cef\AKS.EnterpriseLibrary.WebBrowser.csproj", "{76142658-6E83-4A1C-8CC9-C2574865CA7D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Debug|x64.ActiveCfg = Debug|x64 + {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Debug|x64.Build.0 = Debug|x64 + {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Debug|x86.ActiveCfg = Debug|x86 + {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Debug|x86.Build.0 = Debug|x86 + {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Release|Any CPU.Build.0 = Release|Any CPU + {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Release|x64.ActiveCfg = Release|x64 + {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Release|x64.Build.0 = Release|x64 + {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Release|x86.ActiveCfg = Release|x86 + {76142658-6E83-4A1C-8CC9-C2574865CA7D}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {BDDA2FFD-1C83-470F-82EE-DE0E448EEB6D} + EndGlobalSection +EndGlobal diff --git a/CPF_Cef/AKS.EnterpriseLibrary.WebBrowser.csproj b/CPF_Cef/AKS.EnterpriseLibrary.WebBrowser.csproj new file mode 100644 index 0000000..b4a4f9d --- /dev/null +++ b/CPF_Cef/AKS.EnterpriseLibrary.WebBrowser.csproj @@ -0,0 +1,49 @@ + + + + WinExe + net6.0 + Recent.ico + + AksWebBrowser + AksWebBrowser + AnyCPU;x64;x86 + + + + true + + AnyCPU + + + + true + + AnyCPU + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CPF_Cef/AssistEntity.cs b/CPF_Cef/AssistEntity.cs new file mode 100644 index 0000000..bc200c8 --- /dev/null +++ b/CPF_Cef/AssistEntity.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AksWebBrowser +{ + public enum LightTypeModel + { + FingerLight, + IDCardLight, + BottomLight, + BurnLight + } +} diff --git a/CPF_Cef/Common/COMUtils.cs b/CPF_Cef/Common/COMUtils.cs new file mode 100644 index 0000000..f905d89 --- /dev/null +++ b/CPF_Cef/Common/COMUtils.cs @@ -0,0 +1,173 @@ +using AKS.EnterpriseLibrary.WebBrowser; +using AKSWebBrowser.Commen; +using System; +using System.Collections.Generic; +using System.IO.Ports; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Timers; +using Timer = System.Timers.Timer; +namespace AKSWebBrowser.Common +{ + public class COMUtils + { + private static SerialPort serialPort = new SerialPort(); + public string jsonstr = string.Empty; + public string jsontemp = string.Empty; + public int maxCHunkSize = 1024; + public COMUtils() + { + try + { + + if (!serialPort.IsOpen) + { + OpenCOM("/dev/ttyCH341USB0"); + } + } + catch (Exception ex) + { + try + { + Log.Info("服务启动异常ex: " + ex.Message + ""); + if (!serialPort.IsOpen) + { + OpenCOM("/dev/ttyCH341USB1"); + } + } + catch (Exception ex1) + { + Log.Info("服务启动异常ex1: " + ex1.Message + ""); + } + } + } + + //打开COM口 + public void OpenCOM(string comName) + { + // 设置COM口,波特率,奇偶校验,数据位,停止位 + serialPort.PortName = comName; // 请替换为你的串口名称 + serialPort.BaudRate = 115200; // 设置波特率 + serialPort.Parity = Parity.None; + serialPort.DataBits = 8; + serialPort.StopBits = StopBits.One; + serialPort.Handshake = Handshake.None; + serialPort.DtrEnable = true; //启用控制终端就续信号 + serialPort.ReadTimeout = 50000; + //serialPort.RtsEnable = true; //启用请求发送信号 + serialPort.NewLine = "\n"; + serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); + if (!serialPort.IsOpen) + { + serialPort.Open(); + } + Timer timer = new Timer(3000);//1秒钟的时间间隔 + timer.Elapsed += OnTimedEvent; + timer.AutoReset = true;//重复执行 + timer.Enabled = true;//启动定时器 + Log.Info("浏览器COM服务启动成功"); + } + + //接受数据 + private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) + { + try + { + SerialPort sp = (SerialPort)sender; + string _jsonstr = sp.ReadExisting(); + if (!string.IsNullOrEmpty(_jsonstr)) + { + if (_jsonstr.Contains("\n")) + { + jsonstr = jsontemp + _jsonstr; + jsontemp = string.Empty; + } + else + { + jsontemp = jsontemp + _jsonstr; + } + } + } + catch (Exception ex) + { + Log.Error("接受数据数据异常: " + ex.Message + ""); + jsonstr= MainModel.str2Base64("{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" +"接受数据异常:"+ ex.Message + "\"}"); + } + } + + // 处理接收到的数据 + private void ProcessReceivedData(byte[] data) + { + + // 例如,打印出每个字节的值 + foreach (byte b in data) + { + Log.Info("串口接收byte数据:" + b.ToString()); + } + } + + //打开串口 + private void OnTimedEvent(Object source, ElapsedEventArgs e) + { + try + { + if (!serialPort.IsOpen) + { + serialPort.Open(); + } + } + catch (Exception ex) + { + Log.Error("打开串口异常: " + ex.Message + ""); + } + } + + //发送数据 + public string SendData(string data) + { + try + { + if (serialPort.IsOpen) + { + jsonstr = string.Empty; + jsontemp = string.Empty; + //写入数据并以换行符结束 + serialPort.WriteLine(data); + while (string.IsNullOrEmpty(jsonstr)) + { + Task.Delay(10).Wait(); + } + return jsonstr; + } + else + { + return ""; + } + } + catch (Exception ex) + { + Log.Error("发送数据异常3: " + ex.Message + ""); + return ""; + } + + } + + //关闭 + public void ClosePort() + { + try + { + if (serialPort.IsOpen) + { + serialPort.Close(); // 关闭串口 + } + } + catch (Exception ex) + { + Log.Error("关闭异常: " + ex.Message + ""); + } + } + } +} diff --git a/CPF_Cef/Common/ChunkedUpload.cs b/CPF_Cef/Common/ChunkedUpload.cs new file mode 100644 index 0000000..f6f9759 --- /dev/null +++ b/CPF_Cef/Common/ChunkedUpload.cs @@ -0,0 +1,58 @@ +using Newtonsoft.Json.Linq; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using System.Threading.Tasks; +using CPF.Controls; + +namespace AksWebBrowser.Common +{ + public class ChunkedUpload + { + private readonly HttpClient _httpClient; + + public ChunkedUpload(HttpClient httpClient) + { + _httpClient = httpClient; + } + + public async Task UploadFileAsync(string url, string filePath) + { + string ret = string.Empty; + using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) + { + FileInfo fileInfo = new FileInfo(filePath); + int totalParts = 1; + int chunkNumber = 1; + // 读取文件流其实位置 + var fileStreamPos = 0; + var uploadUrl = $"{url}?partNumber={chunkNumber}&chunks={totalParts}&size={fileInfo.Length}&start={fileStreamPos}&end={fileInfo.Length}&total={fileInfo.Length}&FileName={Path.GetFileName(filePath)}"; + + using (var client = new HttpClient()) + { + + var formData = new MultipartFormDataContent(); + formData.Add(new StreamContent(fileStream, (int)fileStream.Length), "file", Path.GetFileName(filePath) + ".partNumber-1"); + var response = await client.PostAsync(uploadUrl, formData); + var responseString = await response.Content.ReadAsStringAsync(); + fileStream.Close(); + fileStream.Dispose(); + ret = responseString; + JObject jo = (JObject)JsonConvert.DeserializeObject(ret); + if (Convert.ToBoolean(jo["IsSucceed"].ToString()) == true) + { + string result = jo["result"].ToString(); + JObject jo1 = (JObject)JsonConvert.DeserializeObject(result); + ret = jo1["url"].ToString(); + } + } + } + return ret; + } + } +} diff --git a/CPF_Cef/Common/Log.cs b/CPF_Cef/Common/Log.cs new file mode 100644 index 0000000..adc6668 --- /dev/null +++ b/CPF_Cef/Common/Log.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AKSWebBrowser.Commen +{ + public class Log + { + private static StreamWriter streamWriter; //写文件 + + public static void Error(string message) + { + try + { + //DateTime dt = new DateTime(); + string directPath = AppDomain.CurrentDomain.BaseDirectory + @"/logs/error"; //在获得文件夹路径 + if (!Directory.Exists(directPath)) //判断文件夹是否存在,如果不存在则创建 + { + Directory.CreateDirectory(directPath); + } + directPath += string.Format(@"/{0}.log", DateTime.Now.ToString("yyyy-MM-dd")); + if (streamWriter == null) + { + streamWriter = !File.Exists(directPath) ? File.CreateText(directPath) : File.AppendText(directPath); + } + streamWriter.WriteLine("***********************************************************************"); + streamWriter.WriteLine(DateTime.Now.ToString("HH:mm:ss")); + streamWriter.WriteLine("输出信息:错误信息"); + if (message != null) + { + streamWriter.WriteLine("异常信息:\r\n" + message); + } + } + finally + { + if (streamWriter != null) + { + streamWriter.Flush(); + streamWriter.Dispose(); + streamWriter = null; + } + } + } + + public static void Info(string message) + { + try + { + //DateTime dt = new DateTime(); + string directPath = AppDomain.CurrentDomain.BaseDirectory + @"/logs/Info"; //在获得文件夹路径 + if (!Directory.Exists(directPath)) //判断文件夹是否存在,如果不存在则创建 + { + Directory.CreateDirectory(directPath); + } + directPath += string.Format(@"/{0}.log", DateTime.Now.ToString("yyyy-MM-dd")); + if (streamWriter == null) + { + streamWriter = !File.Exists(directPath) ? File.CreateText(directPath) : File.AppendText(directPath); + } + streamWriter.WriteLine("***********************************************************************"); + streamWriter.WriteLine(DateTime.Now.ToString("HH:mm:ss")); + streamWriter.WriteLine("输出信息:信息"); + if (message != null) + { + streamWriter.WriteLine("信息:\r\n" + message); + } + } + finally + { + if (streamWriter != null) + { + streamWriter.Flush(); + streamWriter.Dispose(); + streamWriter = null; + } + } + } + } +} diff --git a/CPF_Cef/CusWebBrowser.cs b/CPF_Cef/CusWebBrowser.cs new file mode 100644 index 0000000..da9e69e --- /dev/null +++ b/CPF_Cef/CusWebBrowser.cs @@ -0,0 +1,39 @@ +using CPF; +using CPF.Cef; +using CPF.Reflection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AKS.EnterpriseLibrary.WebBrowser +{ + + public class CusWebBrowser : CPF.Cef.WebBrowser + { + public CusCefRequestHandler CusRequest = new CusCefRequestHandler(); + public CusWebBrowser() { } + + protected override CpfCefClient OnCreateWebBrowser(CefBrowserSettings settings) + { + CpfCefClient cefClient = base.OnCreateWebBrowser(settings); + cefClient.RequestHandler = CusRequest; + return cefClient; + } + } + + public class CusCefRequestHandler : CpfCefRequestHandler + { + public delegate void CusResquestDelegate(CefPostData postData, CefRequest request); + public event CusResquestDelegate CusResquestEvent; + + public CusCefRequestHandler() { } + + protected override CefResourceRequestHandler GetResourceRequestHandler(CefBrowser browser, CefFrame frame, CefRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling) + { + CusResquestEvent(request.PostData, request); + return null; + } + } +} diff --git a/CPF_Cef/FrmMain.cs b/CPF_Cef/FrmMain.cs new file mode 100644 index 0000000..d38ec6d --- /dev/null +++ b/CPF_Cef/FrmMain.cs @@ -0,0 +1,154 @@ +using AksWebBrowser; +using AKSWebBrowser.Commen; +using CPF; +using CPF.Animation; +using CPF.Cef; +using CPF.Charts; +using CPF.Controls; +using CPF.Drawing; +using CPF.Platform; +using CPF.Shapes; +using CPF.Styling; +using CPF.Svg; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AKS.EnterpriseLibrary.WebBrowser +{ + public class FrmMain : Window + { + protected override void InitializeComponent() + { + LoadStyleFile("res://AksWebBrowser/StyleSheet.css"); + //加载样式文件,文件需要设置为内嵌资源 + Title = "控申业务专用浏览器"; + CanResize = false; + ShowInTaskbar = true; + WindowState = WindowState.Maximized; + Children.Add( + new Border + { + Width = "100%", + Height = "100%", + Child = new Panel + { + Size = SizeField.Fill, + Children = + { + new CusWebBrowser + { + PresenterFor = this, + Name = nameof(webBrowser), + Bindings = + { + { + nameof(CusWebBrowser.Title), + "Title", + this, + BindingMode.OneWayToSource + }, + }, + MarginTop=0, + MarginLeft=0, + MarginRight=0, + MarginBottom=0, + }, + } + } + } + ); + } + private TextBox textBox; + private CusWebBrowser webBrowser; + protected override async void OnInitialized() + { + //窗体大小 + this.Width = 1080; + this.Height = 1920; + //SetTaskStatus.Hidetask(); + base.OnInitialized(); + webBrowser = FindPresenterByName(nameof(webBrowser)); + textBox = FindPresenterByName(nameof(textBox)); + webBrowser.CusRequest.CusResquestEvent += CusRequest_CusResquestEvent; + //浏览器大小 + webBrowser.Width = 1080; + webBrowser.Height = 1920; + webBrowser.Url = "http://192.168.0.57:5173/"; + //webBrowser.Url = Application.StartupPath + @"\html\index.html"; + //开发者工具暂时只能支持Windows + //webBrowser.ShowDev(); + //SetTaskStatus.Showtask(); + webBrowser.LoadEnd += WebBrowser_LoadEnd; + this.Closing += MainWindow_Closing; + } + + //关闭事件 + private void MainWindow_Closing(object sender, ClosingEventArgs e) + { + MainModel.KillProcessByName("AksWebBrowser"); + new MainModel().CLoseCOM(); + } + bool showDev = true; + private void WebBrowser_LoadEnd(object sender, LoadEndEventArgs e) + { + if (!showDev) + { + showDev = true; + webBrowser.ShowDev(); + } + } + + public void Writelog(string str, string dirName = @"logs") + { + try + { + if (string.IsNullOrEmpty(str)) return; + + var baseDir = AppDomain.CurrentDomain.BaseDirectory + dirName; + if (!Directory.Exists(baseDir)) + { + Directory.CreateDirectory(baseDir); + } + string filePath = System.IO.Path.Combine(baseDir, DateTime.Now.ToString("yyyy-MM-dd") + "_log.txt"); + using (StreamWriter sw = File.AppendText(filePath)) + { + sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "[" + str + "]" + "\r\n"); + sw.Flush(); + } + } + catch { } + } + private void CusRequest_CusResquestEvent(CefPostData postData, CefRequest request) + { + string postParams = string.Empty; + if (postData != null) + { + //取提交的参数 + CefPostData cefPostData = postData; + var elements = cefPostData.GetElements(); + foreach (var element in elements) + { + if (element.ElementType == CefPostDataElementType.Bytes) + { + var bytes = element.GetBytes(); + postParams = Encoding.UTF8.GetString(bytes); + Console.WriteLine("请求参数:" + postParams); + } + } + } + + Console.WriteLine("请求地址:" + request.Url.ToString()); + } + + //调用JS内的JS方法 + async void InvokeJS(CpfObject obj, RoutedEventArgs eventArgs) + { + var r = await webBrowser.ExecuteJavaScript("callback('调用绑定到JS里的C#方法')"); + } + } +} diff --git a/CPF_Cef/MainModel.cs b/CPF_Cef/MainModel.cs new file mode 100644 index 0000000..634a27a --- /dev/null +++ b/CPF_Cef/MainModel.cs @@ -0,0 +1,491 @@ +using AksWebBrowser.Common; +using AKSWebBrowser.Commen; +using AKSWebBrowser.Common; +using CPF.Cef; +using System; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Net.Http; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using static System.Net.Mime.MediaTypeNames; + +namespace AKS.EnterpriseLibrary.WebBrowser +{ + public class MainModel : CPF.CpfObject + { + public COMUtils com = new COMUtils(); + + /// + /// 读取身份证卡号 + /// + /// + /// + [JSFunction] + public string IDCardRead(string paramsString) + { + try + { + paramsString = "{\"type\":\"1\",\"param\":{\"data\":\"" + "" + "\"}}"; + Log.Info("读取身份证卡号: " + paramsString + ""); + string base64 = str2Base64(paramsString); + string str = com.SendData(base64); + if (string.IsNullOrEmpty(str)) + { + return "{\"message\":\"success\",\"code\":\"400\",\"status\":false,\"data\":\"" + "获取数据失败" + "\"}"; + } + else + { + return Base64str2(str); + } + } + catch (Exception ex) + { + Log.Error("读取身份证卡号异常: " + ex.Message + ""); + return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}"; + } + } + + /// + /// 打印排队票据 + /// + /// 排号 + /// 等待人数 + /// 二维码 + /// 办理业务名称 + /// + [JSFunction] + public string SendByPrint(string ph, string ddrs, string qrcode, string ywmc) + { + try + { + string paramsString = "{\"type\":\"2\",\"param\":{\"ph\":\"" + ph + "\",\"ddrs\":\"" + ddrs + "\",\"qrcode\":\"" + qrcode + "\",\"ywmc\":\"" + ywmc + "\"}}"; + Log.Info("打印排队票据: " + paramsString + ""); + string base64 = str2Base64(paramsString); + string str = com.SendData(base64); + if (string.IsNullOrEmpty(str)) + { + return "{\"message\":\"success\",\"code\":\"400\",\"status\":false,\"data\":\"" + "打印排队票据失败" + "\"}"; + } + else + { + return Base64str2(str); + } + } + catch (Exception ex) + { + Log.Error("打印排队票据异常: " + ex.Message + ""); + return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}"; + } + } + + /// + /// 文字语音播报 + /// + /// + /// + /// + [JSFunction] + public string payleText(string text, bool ispaye) + { + try + { + if (text.Length > 65535) + { + return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":" + "文字太长" + "}"; + } + string paramsString = "{\"type\":\"3\",\"param\":{\"text\":\"" + text + "\",\"ispaye\":\"" + ispaye + "\"}}"; + Log.Info("文字语音播报: " + paramsString + ""); + string base64 = str2Base64(paramsString); + if (base64.Length > 1024) + { + string url = "http://192.168.0.34:92/api/UploadFP/UploadFP"; + Task.Run(async () => + { + DateTime dateTime = DateTime.Now; + string time = DateTime.Now.ToString( + "yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo); + var dirpath = Path.Combine(Environment.CurrentDirectory, "wwwroot", "TempFile"); + if (!Directory.Exists(dirpath)) + { + Directory.CreateDirectory(dirpath); + } + var filepath = Path.Combine(dirpath, time); + string path = dirpath + @"/" + time + ".txt"; + base64 = str2Base64(text); + byte[] bytes = Convert.FromBase64String(base64); + System.IO.FileStream stream = new System.IO.FileStream(path, System.IO.FileMode.CreateNew); + System.IO.BinaryWriter writer = new System.IO.BinaryWriter(stream); + writer.Write(bytes, 0, bytes.Length); + writer.Close(); + Log.Info("文字语音播报临时文件: " + path + ""); + UploadInfo(url, path); + }); + @event2.WaitOne(); + Regex re = new Regex(@"(((?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(:[0-9]+)?|(?:ww‌​w.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?‌​(?:[\w]*))?)"); + MatchCollection mc = re.Matches(url);//获取的是一个数组 + string pdfurl = mc[0].ToString() + "://" + mc[1].ToString() + urlpath; + paramsString = "{\"type\":\"3\",\"param\":{\"text\":\"" + pdfurl + "\",\"ispaye\":\"" + ispaye + "\"}}"; + Log.Info("文字语音播报: " + paramsString + ""); + base64 = str2Base64(paramsString); + } + string str = com.SendData(base64); + if (string.IsNullOrEmpty(str)) + { + return "{\"message\":\"success\",\"code\":\"400\",\"status\":false,\"data\":\"" + "文字语音播报失败" + "\"}"; + } + else + { + return Base64str2(str); + } + } + catch (Exception ex) + { + Log.Error("文字语音播报异常: " + ex.Message + ""); + return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}"; + } + } + + /// + /// 发送短信 + /// + /// + /// + /// + [JSFunction] + public string SendSSM(string content, string phone) + { + try + { + string paramsString = "{\"type\":\"4\",\"param\":{\"content\":\"" + content + "\",\"phone\":\"" + phone + "\"}}"; + Log.Info("发送短信: " + paramsString + ""); + string base64 = str2Base64(paramsString); + string str = com.SendData(base64); + if (string.IsNullOrEmpty(str)) + { + return "{\"message\":\"success\",\"code\":\"400\",\"status\":false,\"data\":\"" + "发送短信失败" + "\"}"; + } + else + { + return Base64str2(str); + } + } + catch (Exception ex) + { + Log.Error("发送短信异常: " + ex.Message + ""); + return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}"; + } + } + + /// + /// 打开高拍仪并且进行快速扫描文件 + /// + /// + /// + [JSFunction] + public string openCamera(string url) + { + try + { + string paramsString = "{\"type\":\"5\",\"param\":{\"url\":\"" + url + "\"}}"; + Log.Info("打开高拍仪并且进行快速扫描文件: " + paramsString + ""); + string base64 = str2Base64(paramsString); + string str = com.SendData(base64); + if (string.IsNullOrEmpty(str)) + { + return "{\"message\":\"success\",\"code\":\"400\",\"status\":false,\"data\":\"" + "打开高拍仪并且进行快速扫描文件失败" + "\"}"; + } + else + { + return Base64str2(str); + } + } + catch (Exception ex) + { + Log.Error("打开高拍仪并且进行快速扫描文件异常: " + ex.Message + ""); + return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}"; + } + } + + /// + /// 打开签字版 + /// + /// + /// + [JSFunction] + public string OpenSign(string paramsString) + { + try + { + paramsString = "{\"type\":\"6\",\"param\":{\"data\":\"" + "" + "\"}}"; + Log.Info("打开签字版: " + paramsString + ""); + string base64 = str2Base64(paramsString); + string str = com.SendData(base64); + if (string.IsNullOrEmpty(str)) + { + return "{\"message\":\"success\",\"code\":\"400\",\"status\":false,\"data\":\"" + "打开签字版失败" + "\"}"; + } + else + { + return Base64str2(str); + } + } + catch (Exception ex) + { + Log.Error("打开签字版异常: " + ex.Message + ""); + return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}"; + } + } + + /// + /// 关闭签字版 + /// + /// + /// + [JSFunction] + public string CloseSign(string paramsString) + { + try + { + paramsString = "{\"type\":\"7\",\"param\":{\"data\":\"" + "" + "\"}}"; + Log.Info("关闭签字版: " + paramsString + ""); + string base64 = str2Base64(paramsString); + string str = com.SendData(base64); + if (string.IsNullOrEmpty(str)) + { + return "{\"message\":\"success\",\"code\":\"400\",\"status\":false,\"data\":\"" + "关闭签字版失败" + "\"}"; + } + else + { + return Base64str2(str); + } + } + catch (Exception ex) + { + Log.Error("关闭签字版异常: " + ex.Message + ""); + return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}"; + } + } + + /// + /// 获取签字版数据 + /// + /// + /// + [JSFunction] + public string GetSignData(string url) + { + try + { + string paramsString = "{\"type\":\"8\",\"param\":{\"url\":\"" + url + "\"}}"; + Log.Info("获取签字版数据: " + paramsString + ""); + string base64 = str2Base64(paramsString); + string str = com.SendData(base64); + if (string.IsNullOrEmpty(str)) + { + return "{\"message\":\"success\",\"code\":\"400\",\"status\":false,\"data\":\"" + "获取签字版数据失败" + "\"}"; + } + else + { + return Base64str2(str); + } + } + catch (Exception ex) + { + Log.Error("获取签字版数据异常: " + ex.Message + ""); + return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}"; + } + } + + /// + /// 开始录音、取消录音、结束录音 + /// + /// + /// + /// + [JSFunction] + public string SoundRecording(bool isopen, string url) + { + try + { + string paramsString = "{\"type\":\"11\",\"param\":{\"isopen\":\"" + isopen + "\",\"url\":\"" + url + "\"}}"; + Log.Info("开始录音、取消录音、结束录音: " + paramsString + ""); + string base64 = str2Base64(paramsString); + string str = com.SendData(base64); + if (string.IsNullOrEmpty(str)) + { + return "{\"message\":\"success\",\"code\":\"400\",\"status\":false,\"data\":\"" + "开始录音、取消录音、结束录音失败" + "\"}"; + } + else + { + return Base64str2(str); + } + } + catch (Exception ex) + { + Log.Error("开始录音、取消录音、结束录音异常: " + ex.Message + ""); + return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}"; + } + } + + /// + /// 根据文件地址在线打印 + /// + /// + /// + [JSFunction] + public string PrintFile(string url, string ext) + { + try + { + string paramsString = "{\"type\":\"9\",\"param\":{\"url\":\"" + url + "\",\"ext\":\"" + ext + "\"}}"; + Log.Info("根据文件地址在线打印: " + paramsString + ""); + string base64_1 = str2Base64(paramsString); + string str = com.SendData(base64_1); + if (string.IsNullOrEmpty(str)) + { + return "{\"message\":\"success\",\"code\":\"400\",\"status\":false,\"data\":\"" + "根据文件地址在线打印失败" + "\"}"; + } + else + { + return Base64str2(str); + } + } + catch (Exception ex) + { + Log.Error("根据文件地址在线打印异常: " + ex.Message + ""); + return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}"; + } + + } + + /// + /// 根据文件base64打印 + /// + /// + /// + /// + [JSFunction] + public string PrintBase64(string url, string base64, string ext) + { + try + { + Task.Run(async () => + { + DateTime dateTime = DateTime.Now; + string time = DateTime.Now.ToString( + "yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo); + var dirpath = Path.Combine(Environment.CurrentDirectory, "wwwroot", "PrintFile"); + if (!Directory.Exists(dirpath)) + { + Directory.CreateDirectory(dirpath); + } + var filepath = Path.Combine(dirpath, time); + string path = dirpath + @"/" + time + "." + ext; + byte[] bytes = Convert.FromBase64String(base64); + System.IO.FileStream stream = new System.IO.FileStream(path, System.IO.FileMode.CreateNew); + System.IO.BinaryWriter writer = new System.IO.BinaryWriter(stream); + writer.Write(bytes, 0, bytes.Length); + writer.Close(); + Log.Info("根据文件base64打印: " + path + ""); + UploadInfo(url, path); + }); + @event2.WaitOne(); + Regex re = new Regex(@"(((?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(:[0-9]+)?|(?:ww‌​w.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?‌​(?:[\w]*))?)"); + MatchCollection mc = re.Matches(url);//获取的是一个数组 + string pdfurl = mc[0].ToString() + "://" + mc[1].ToString() + urlpath; + Log.Info("根据文件base64打印: " + pdfurl + ""); + try + { + string paramsString = "{\"type\":\"9\",\"param\":{\"url\":\"" + pdfurl + "\",\"ext\":\"" + ext + "\"}}"; + Log.Info("根据文件base64打印: " + paramsString + ""); + string base64_1 = str2Base64(paramsString); + string str = com.SendData(base64_1); + if (string.IsNullOrEmpty(str)) + { + return "{\"message\":\"success\",\"code\":\"400\",\"status\":false,\"data\":\"" + "根据文件base64打印失败" + "\"}"; + } + else + { + return Base64str2(str); + } + } + catch (Exception ex) + { + Log.Error("根据文件base64打印异常: " + ex.Message + ""); + return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}"; + } + + + } + catch (Exception ex) + { + return "{\"message\":\"fali\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}"; + } + } + + /// + /// 初始文件上传 + /// + private string urlpath = string.Empty; + private AutoResetEvent @event2 = new AutoResetEvent(false); + private async void UploadInfo(string url, string srpath) + { + var httpClient = new HttpClient(); + var uploader = new ChunkedUpload(httpClient); + urlpath = await uploader.UploadFileAsync(url, srpath); + @event2.Set(); + } + + /// + /// string 转换为 base64 + /// + /// + public static string str2Base64(string str) + { + byte[] b = System.Text.Encoding.UTF8.GetBytes(str); + string result = Convert.ToBase64String(b); + return result; + } + + /// + /// base64 转换为 string + /// + /// + public static string Base64str2(string data) + { + byte[] c = Convert.FromBase64String(data); + string result = System.Text.Encoding.UTF8.GetString(c); + Log.Info("接收返回数据:" + result); + return result; + } + + /// + /// 根据程序名称杀死进程 + /// + /// + public static void KillProcessByName(string processName) + { + Process[] processes = Process.GetProcessesByName(processName); + foreach (Process process in processes) + { + try + { + process.Kill(); + process.WaitForExit(); // 等待进程退出 + } + catch (Exception ex) { } + } + } + + /// + /// 关闭串口 + /// + public void CLoseCOM() + { + com.ClosePort(); + } + } +} diff --git a/CPF_Cef/Program.cs b/CPF_Cef/Program.cs new file mode 100644 index 0000000..7e53444 --- /dev/null +++ b/CPF_Cef/Program.cs @@ -0,0 +1,38 @@ +using CPF.Cef; +using CPF.Linux;//如果需要支持Linux才需要 +using CPF.Mac;//如果需要支持Mac才需要 +using CPF.Platform; +using CPF.Skia; +using CPF.Windows; +using System; + +namespace AKS.EnterpriseLibrary.WebBrowser +{ + class Program + { + [STAThread] + static void Main(string[] args) + { + Application.Initialize( + (OperatingSystemType.Windows, new WindowsPlatform(), new SkiaDrawingFactory()) + , (OperatingSystemType.OSX, new MacPlatform(), new SkiaDrawingFactory())//如果需要支持Mac才需要 + , (OperatingSystemType.Linux, new LinuxPlatform(), new SkiaDrawingFactory())//如果需要支持Linux才需要 + ); + + CefRuntime.Load(); + var mainArgs = new CpfCefMainArgs(args); + var app = new CpfCefApp(); + var exitCode = CefRuntime.ExecuteProcess(mainArgs, app, IntPtr.Zero); + if (exitCode != -1) + { + return; + } + CefRuntime.Initialize(mainArgs, new CefSettings { }, app, IntPtr.Zero); + + var model = new MainModel(); + Application.Run(new FrmMain { DataContext = model, CommandContext = model }); + + CefRuntime.Shutdown(); + } + } +} diff --git a/CPF_Cef/Recent.ico b/CPF_Cef/Recent.ico new file mode 100644 index 0000000..a05686b Binary files /dev/null and b/CPF_Cef/Recent.ico differ diff --git a/CPF_Cef/SetTaskStatus.cs b/CPF_Cef/SetTaskStatus.cs new file mode 100644 index 0000000..9d28f48 --- /dev/null +++ b/CPF_Cef/SetTaskStatus.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace AksWebBrowser +{ + public class SetTaskStatus + { + private const int SW_HIDE = 0; //隐藏任务栏 + private const int SW_RESTORE = 9;//显示任务栏 + + [DllImport("user32.dll")] + private static extern int ShowWindow(int hwnd, int nCmdShow); + [DllImport("user32.dll")] + private static extern int FindWindow(string lpClassName, string lpWindowName); + + /// + /// 显示任务栏 + /// + public static void Showtask() + { + ShowWindow(FindWindow("Shell_TrayWnd", null), SW_RESTORE); + } + /// + /// 隐藏任务栏 + /// + public static void Hidetask() + { + ShowWindow(FindWindow("Shell_TrayWnd", null), SW_HIDE); + } + + + + // 设置窗体的显示状态 + [DllImport("user32.dll", SetLastError = true)] + public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, + int X, int Y, int cx, int cy, uint uFlags); + + // 窗体的句柄 + [DllImport("user32.dll")] + public static extern IntPtr GetForegroundWindow(); + + public const uint SWP_SHOWWINDOW = 0x0040; + public const uint SWP_NOSIZE = 0x0001; + public const uint SWP_NOMOVE = 0x0002; + public const uint TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW; + } +} diff --git a/CPF_Cef/StyleSheet.css b/CPF_Cef/StyleSheet.css new file mode 100644 index 0000000..db1d459 --- /dev/null +++ b/CPF_Cef/StyleSheet.css @@ -0,0 +1,473 @@ + +@media windows { + * { + FontFamily: '微软雅黑'; /*不同系统的字体不同,自己根据情况改或者使用内嵌字体*/ + } +} + +@media osx { + * { + FontFamily: '苹方-简'; + } +} + +@media linux { + * { + FontFamily: '文泉驿正黑'; + } +} +/*设置窗体标题栏背景颜色圆角*/ +/*#caption { + IsAntiAlias: true; + Background: #2c2c2c; + CornerRadius:5,5,0,0; +} +#frame { + CornerRadius: 5; + IsAntiAlias: true; +}*/ +Button { + BorderFill: #DCDFE6; + IsAntiAlias: True; + CornerRadius: 4,4,4,4; + Background: #FFFFFF; +} + + Button[IsMouseOver=true] { + BorderFill: rgb(198,226,255); + Background: rgb(236,245,255); + Foreground: rgb(64,158,255); + } + + Button[IsPressed=true] { + BorderFill: rgb(58,142,230); + } + + Button.primary { + BorderFill: rgb(64,158,255); + CornerRadius: 4,4,4,4; + Background: rgb(64,158,255); + Foreground: #FFFFFF; + } + + Button.primary[IsMouseOver=true] { + BorderFill: rgb(102,177,255); + Background: rgb(102,177,255); + Foreground: #FFFFFF; + } + + Button.primary[IsPressed=true] { + BorderFill: rgb(58,142,230); + Background: rgb(58,142,230); + } + + Button.success { + BorderFill: rgb(103,194,58); + CornerRadius: 4,4,4,4; + Background: rgb(103,194,58); + Foreground: #FFFFFF; + } + + Button.success[IsMouseOver=true] { + BorderFill: rgb(133,206,97); + Background: rgb(133,206,97); + Foreground: #FFFFFF; + } + + Button.success[IsPressed=true] { + BorderFill: rgb(93,175,52); + Background: rgb(93,175,52); + } + + Button.danger { + BorderFill: rgb(245,108,108); + Background: rgb(245,108,108); + CornerRadius: 4,4,4,4; + Foreground: #FFFFFF; + } + + Button.danger[IsMouseOver=true] { + BorderFill: rgb(247,137,137); + Background: rgb(247,137,137); + Foreground: #FFFFFF; + } + + Button.danger[IsPressed=true] { + BorderFill: rgb(221,97,97); + Background: rgb(221,97,97); + } + + +TextBox, .textBox, DatePicker { + Background: #fff; + IsAntiAlias: true; + BorderFill: #DCDFE6; + CornerRadius: 4,4,4,4; + BorderStroke: 1; +} + + .groupPanel TextBox, DatePicker TextBox, .textBox TextBox { + BorderStroke: 0; + } + + .textBox[IsKeyboardFocusWithin=true] { + BorderFill: #1E9FFF; + } + +.singleLine { /*单行文本框*/ + AcceptsReturn: false; + HScrollBarVisibility: Hidden; + VScrollBarVisibility: Hidden; +} + + .singleLine #contentPresenter { + Padding: 3; + } + +.multiline { /*多行文本框*/ +} + + +.slotLeft { + CornerRadius: 0,4,4,0; + BorderFill: #DCDFE6; + Background: #F5F7FA; + BorderThickness: 1,0,0,0; + BorderType: BorderThickness; + MarginTop: 0; + MarginBottom: 0; + MarginRight: 0; +} + +RadioButton #radioButtonBorder { + StrokeFill: rgb(220,223,230); +} + +RadioButton[IsChecked=true] #radioButtonBorder { + StrokeFill: #1E9FFF; + Fill: #1E9FFF; +} + +RadioButton #optionMark { + StrokeFill: #1E9FFF; + Fill: #fff; +} + +CheckBox #indeterminateMark { + Fill: #1E9FFF; +} + +CheckBox #checkBoxBorder { + Background: #fff; + BorderFill: rgb(220,223,230); +} + +CheckBox[IsChecked=true] #checkBoxBorder { + Background: #1E9FFF; + BorderFill: #1E9FFF; +} + +CheckBox Polyline { + StrokeFill: #fff; +} + +.radioGroup { + BorderType: BorderThickness; + BorderFill: rgb(220,223,230); + BorderThickness: 1,1,0,1; +} + + .radioGroup RadioButton { + BorderType: BorderThickness; + BorderFill: rgb(220,223,230); + BorderThickness: 0,0,1,0; + } + + .radioGroup RadioButton #markPanel { + Visibility: Collapsed; + } + + .radioGroup RadioButton TextBlock { + Margin: 5; + } + + .radioGroup RadioButton[IsChecked=true] { + Background: rgb(64,158,255); + Foreground: #fff; + } + +.error { + Foreground: #f00; + Visibility: Collapsed; +} + + .error[DesignMode=true] { + Visibility: Visible; + } + +.twoLine[AttachedExtenstions.IsError=true] .error { + Visibility: Visible; +} + +.twoLine[AttachedExtenstions.IsError=true] .textBox { + BorderFill: #f00; +} + +ScrollBar { + Background: null; +} + + ScrollBar Thumb { + IsAntiAlias: true; + CornerRadius: 5; + } + + ScrollBar[Orientation=Horizontal] { + Height: 12; + } + + ScrollBar[Orientation=Vertical] { + Width: 12; + } + + ScrollBar #PART_LineUpButton, ScrollBar #PART_LineDownButton { + Visibility: Collapsed; + } + +ComboBox { + Background: #fff; + IsAntiAlias: true; + BorderFill: #DCDFE6; + CornerRadius: 4,4,4,4; + BorderStroke: 1; +} + + ComboBox[IsKeyboardFocusWithin=true] { + BorderFill: #1E9FFF; + } + +#DropDownPanel TextBlock { + MarginLeft: 5; + MarginTop: 2; + MarginBottom: 2; + font-size: 14; +} + +#dropDownBorder { + ShadowBlur: 2; + ShadowColor: rgba(0, 0, 0, 0.4); + BorderStroke: 0; +} + +#DropDownPanel[IsMouseOver=false] ScrollBar { + Visibility: Collapsed; +} + +#DropDownPanel ScrollBar[Orientation=Horizontal] { + Height: 10; +} + +#DropDownPanel ScrollBar[Orientation=Vertical] { + Width: 10; +} + +Slider { + IsAntiAlias: true; +} + + Slider Thumb { + IsAntiAlias: true; + Width: 16; + Height: 16; + CornerRadius: 7; + BorderFill: rgb(64,158,255); + BorderStroke: 2; + Background: #fff; + ZIndex: 1; + } + + + Slider Thumb[IsMouseOver=true] { + animation-name: sliderMouseOver; + animation-duration: 0.1s; + animation-iteration-count: 1; + animation-fill-mode: forwards; + } + + Slider #TrackBackground { + CornerRadius: 2; + Background: rgb(228,231,237); + BorderStroke: 0; + } + + Slider #decreaseRepeatButton { + Background: rgb(64,158,255); + CornerRadius: 2; + } + + Slider[Orientation=Horizontal] #decreaseRepeatButton { + Height: 4; + MarginLeft: 5; + } + + Slider[Orientation=Vertical] #decreaseRepeatButton { + Width: 4; + MarginBottom: 5; + } + +ProgressBar { + CornerRadius: 5; + IsAntiAlias: true; + BorderFill: null; + Background: rgb(235,238,245); +} + + ProgressBar #Indicator, ProgressBar #Animation { + CornerRadius: 5; + } + +NumericUpDown { + Background: #fff; + IsAntiAlias: true; + BorderFill: #DCDFE6; + CornerRadius: 4,4,4,4; + BorderStroke: 1; +} + + NumericUpDown RepeatButton { + Width: 20; + Background: rgb(245,247,250); + } + + NumericUpDown #decreaseBtn { + CornerRadius: 4,0,0,4; + } + + NumericUpDown #increaseBtn { + CornerRadius: 0,4,4,0; + } + + NumericUpDown #textBoxBorder { + BorderFill: #DCDFE6; + } + + NumericUpDown TextBox { + BorderStroke: 0; + } + +.widget { + IsAntiAlias: true; + BorderFill: #DCDFE6; + CornerRadius: 4,4,4,4; + BorderStroke: 1; +} + +.widgetHead { + Background: linear-gradient(0 0,0 100%,#F7F7F7 0,#F0F0F0 1); + BorderType: BorderThickness; + BorderThickness: 0,0,0,1; + BorderFill: #DCDFE6; +} + +DataGrid { + Foreground: #7a7a7a; +} + +DataGridCellTemplate, DataGridRow, DataGrid, .DataGridCell { + BorderFill: rgb(235,238,245); +} + +DataGridRow { + Height: 36; +} + + DataGridRow[IsMouseOver=true] { + Background: rgb(245,247,250); + } + + DataGridRow[IsSelected=true] { + Background: rgb(245,247,250); + } + +DataGridColumnTemplate { + Height: 38; + FontSize: 15; + FontStyle: Bold; + Background: #fff; + BorderFill: rgb(235,238,245); +} + +TabControl #headBorder { + Background: #fff; +} + +TabItem > Border { + BorderThickness: 0,0,0,2; +} + +TabItem[IsSelected=true] > Border { + BorderFill: #1E9FFF; +} + +TabItem[IsSelected=true] { + Foreground: #1E9FFF; +} + +TabControl[TabStripPlacement=Left] TabItem, TabControl[TabStripPlacement=Right] TabItem { + Width: 100%; + BorderType: BorderThickness; + BorderThickness: 0,0,0,1; + BorderFill: #e8e8e8; +} + + TabControl[TabStripPlacement=Left] TabItem TextBlock { + MarginRight: 0; + } + + TabControl[TabStripPlacement=Left] TabItem > Border { + Width: 100%; + } + +TabControl[TabStripPlacement=Left] #headerPanel, TabControl[TabStripPlacement=Right] #headerPanel { + Width: 100; + Background: rgb(245,247,250); +} + +.closeBtn[IsMouseOver=true] { + Fill: #171717; +} + +.placeholder { + IsHitTestVisible: false; + Foreground: "192,196,204"; + Visibility: Collapsed; +} + +.textBox[AttachedExtenstions.IsEmpty=true] .placeholder { + Visibility: Visible; +} + +.loginBox TextBox, .loginBox .placeholder { + FontSize: 16; +} + +.loginBox CheckBox { + Foreground: #757575; +} + +.searchBox Button { + CornerRadius: 0,4,4,0, +} + +#MenuPop #menuPanel > Border, #MenuPop ContextMenu > Border { + Background: #fff; + ShadowColor: rgba(0, 0, 0, 0.4); +} + +#MenuPop MenuItem[IsMouseOver=true] { + Background: #DCDFE6; +} + +ListBoxItem { + Width: 100%; +} \ No newline at end of file