using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Winsoft.GOV.XF.WebApi.WXCore.Models; using Newtonsoft.Json; using Winsoft.GOV.XF.WebApi.WXCore.Data; using Microsoft.Extensions.Logging; using System.Net; using Senparc.Weixin.Entities; using Microsoft.Extensions.Options; using Microsoft.Extensions.Configuration; using Newtonsoft.Json.Linq; namespace Winsoft.GOV.XF.WebApi.WXCore.Services { public class XFApiService : BaseService { public delegate void OnFails(string message); BundlesService _bundlesService; public XFApiService(BundlesService bundlesService, XFDbContext context, ILoggerFactory loggerFactory, IConfigurationRoot config) :base(context, loggerFactory, config) { _bundlesService = bundlesService; } public async Task PostAssets(Bundle b) { string end = "\r\n"; string twoHyphens = "--"; string boundary = "*****"; byte[] endbyte = Encoding.UTF8.GetBytes(end); byte[] twoHyphensbyte = Encoding.UTF8.GetBytes(twoHyphens); byte[] boundarybyte = Encoding.UTF8.GetBytes(boundary); HttpClientHandler handler = new HttpClientHandler(); HttpClient client = new HttpClient(handler); MemoryStream ms = new MemoryStream(); int j = 0; for (int i = 0; i < b.Assets.Count(); i++) { Asset a = b.Assets.ElementAt(i); if (a.AssetType != AssetType.Image) continue; ms.Write(twoHyphensbyte, 0, twoHyphensbyte.Length); ms.Write(boundarybyte, 0, boundarybyte.Length); ms.Write(endbyte, 0, endbyte.Length); byte[] s = Encoding.UTF8.GetBytes(String.Format("Content-Disposition: form-data; name=\"file{0}\";filename=\"{1}\"\r\n", j, a.FileName)); ms.Write(s, 0, s.Length); ms.Write(endbyte, 0, endbyte.Length); await ms.WriteAsync(a.FileBytes, 0, a.FileBytes.Length); ms.Write(endbyte, 0, endbyte.Length); j++; } ms.Write(twoHyphensbyte, 0, twoHyphensbyte.Length); ms.Write(boundarybyte, 0, boundarybyte.Length); ms.Write(twoHyphensbyte, 0, twoHyphensbyte.Length); ms.Write(endbyte, 0, endbyte.Length); HttpContent hc = new StreamContent(ms); hc.Headers.Add("APIKey", "MUA5NmU3OTIxOEPSOFTDQ1YTMzMDExMg"); client.DefaultRequestHeaders.Add("Accept", "*/*"); client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); client.DefaultRequestHeaders.Add("Connection", "Keep-Alive"); client.DefaultRequestHeaders.Add("Charset", "UTF-8"); hc.Headers.Add("Content-Type", "Multipart/Form-Data; Boundary=" + boundary); var r = await client.PostAsync(_config["XFApi"] + "/letter/uploadFile;app_id=" + b.LetterId, hc); if (r.StatusCode != HttpStatusCode.OK) { Logger.LogError("省统一平台异常反馈:状态“{0}”", r.StatusCode); return false; } byte[] tmp = await r.Content.ReadAsByteArrayAsync(); string rStr = Encoding.UTF8.GetString(tmp); Logger.LogInformation(rStr); JObject rObj = JsonConvert.DeserializeObject(rStr); if (rObj == null) { Logger.LogError("数据提交省统一平台失败,原因:{0}", "数据为空"); return false; } return true; } /// /// 提交信件 /// /// 信件内容 /// 失败回调 /// public async Task PostLetter(Bundle b, string absoluteUri, OnFails onFails) { string d = b.Describe; if (b.Assets.Count() > 0) //d += "(此信件内容含有其他多媒体信息,详细请复制网址到浏览器打开:" + _bundlesService.GenerateBaseURL(b, absoluteUri) + ")"; d += "\r\n【扩展信息链接:" + _bundlesService.GenerateSampleBaseURL(b, absoluteUri) + "】"; string s = "advice={0};type={1};name={2};phone={3};is_public={4};content={5};title={6};county_id={7};unit_id={8};sswz=8;ly=2; user_id={9}"; s = String.Format(s, b.Advice, b.Type.ToString(), b.Name, b.Mobile, b.IsPublic.ToString(), d, b.Title, b.County_id, b.Unit_id, b.OpenID); XFApiResult rObj = await HttpPostAsync(_config["XFApi"] + "/letter/submitLetter;", s, onFails); if (rObj == null) return false; if (rObj.Data == null || !rObj.Data.Success) { Logger.LogError("数据提交省统一平台失败,原因:{0}", rObj.Message); onFails(string.Format("数据提交省统一平台失败,原因:{0}", rObj.Message)); return false; } b.SearchCode = rObj.Data.Data; await _bundlesService.UpdateSearchCode(b); string s2; Bundle b2 = await GetBundleByQueryCode(b.SearchCode, e => s2 = e ); if (b2 !=null) { b.LetterId = b2.LetterId; b.Status = b2.Status; b.Reply = b2.Reply; b.DealProcesses = b2.DealProcesses; b.ResultFromXF = b2.ResultFromXF; } return true; } /// /// 查询码是否有效 /// /// 查询码 /// 失败回调 /// public async Task QueryCodeIsValid(string queryCode, OnFails onFails) { XFApiResult rObj = await HttpPostAsync(_config["XFApi"] + "/query/code;", "query_code=" + queryCode, onFails); if (rObj == null) return false; if (rObj.Data == null || !rObj.Data.Success) { Logger.LogError("数据提交省统一平台失败,原因:{0}", rObj.Message); onFails(string.Format("数据提交省统一平台失败,原因:{0}", rObj.Message)); return false; } return true; } /// /// 查询信件详细信息 /// /// 查询码 /// 失败回调 /// public async Task GetBundleByQueryCode(string queryCode, OnFails onFails) { JObject rObj = await HttpGetAsync(_config["XFApi"] + "/query/letterDetail;", "query_code="+ queryCode, onFails); if (rObj == null) return null; if(String.IsNullOrWhiteSpace(rObj["data"]["letter"]["id"].ToString())) { Logger.LogError("省统一平台无该信件信息,查询码:{0}", queryCode); onFails(string.Format("查找不到该信件信息。")); return null; } Bundle bundle = new Bundle(); bundle.LetterId = rObj["data"]["letter"]["id"].ToString(); bundle.Status = rObj["data"]["letter"]["status"].ToString(); bundle.Reply = rObj["data"]["letter"]["replyAdvice"].ToString(); bundle.DealProcesses = rObj["data"]["dealProcesses"].ToString(); bundle.ResultFromXF = rObj["data"].ToString(); return bundle; } /// /// 是否可评价 /// /// /// /// public async Task IsEvaluate(string letter_id, OnFails onFails) { XFApiIsEvaluateResult rObj = await HttpGetAsync(_config["XFApi"] + "/query/isEvaluate;", "letter_id=" + letter_id, onFails); if (rObj == null) return null; if (rObj.Status == "10201") { Logger.LogError("查询信件是否可评价失败:{0}", letter_id); onFails(string.Format("查询信件是否可评价失败,原因:{0}", rObj.Message)); return null; } return rObj.Data; } /// /// 评价 /// /// /// /// //http://<服务器IP>/query/submitEvaluate public async Task SubmitEvaluate(EvaluateModel e, OnFails onFails) { XFApiResult rObj = await HttpPostAsync(_config["XFApi"] + "/query/submitEvaluate;", String.Format( "cxm={0};xfbmmyd={1};zrdwmyd={2};type=1;xfbmpjsj={3};xfbmpjnr={4};zrdwpjsj={5};zrdwpjnr={6};", e.cxm, e.xfbmmyd, e.zrdwmyd, DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"), e.xfbmpjnr, DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"), e.zrdwpjnr), onFails); if (rObj == null) return false; if (rObj.Data == null) { Logger.LogError("数据提交省统一平台失败,原因:{0}", rObj.Message); onFails(string.Format("数据提交省统一平台失败,原因:{0}", rObj.Message)); return false; } return rObj.Data.Success; } /// /// 查询满意度 /// /// /// /// //http://<服务器IP>/query/submitEvaluate public async Task QueryEvaluate(string searchCode, OnFails onFails) { JObject rObj = await HttpGetAsync(_config["XFApi"] + "/query/queryEvaluate;", String.Format("cxm={0}", searchCode), onFails); if (rObj == null) return null; if (rObj["status"].ToString() == "10201") { Logger.LogError("数据提交省统一平台失败,原因:{0}", rObj["message"].ToString()); onFails(string.Format("数据提交省统一平台失败,原因:{0}", rObj["message"].ToString())); return null; } Logger.LogInformation(rObj.ToString()); EvaluateModel em = new EvaluateModel(); em.type = rObj["data"]["type"].ToString(); em.xfbmmyd = rObj["data"]["xfbmmyd"].ToString(); em.xfbmpjnr = rObj["data"]["xfbmpjnr"].ToString(); em.xfbmpjsj = rObj["data"]["xfbmpjsj"].ToString(); em.zrdwmyd = rObj["data"]["zrdwmyd"].ToString(); em.zrdwpjnr = rObj["data"]["zrdwpjnr"].ToString(); em.zrdwpjsj = rObj["data"]["zrdwpjsj"].ToString(); return em; } /// /// POST 异步 /// /// /// /// /// /// async Task HttpPostAsync(string url, string formData, OnFails onFails) { HttpClientHandler handler = new HttpClientHandler(); HttpClient client = new HttpClient(handler); MemoryStream ms = new MemoryStream(); HttpContent hc = new StreamContent(ms); hc.Headers.Add("APIKey", "MUA5NmU3OTIxOEPSOFTDQ1YTMzMDExMg"); var r = await client.PostAsync(url + WebUtility.UrlEncode(formData), hc); if (r.StatusCode != HttpStatusCode.OK) { Logger.LogError("省统一平台异常反馈:状态“{0}”", r.StatusCode); onFails(string.Format("省统一平台异常反馈:状态“{0}”", r.StatusCode)); return default(T); } byte[] tmp = await r.Content.ReadAsByteArrayAsync(); string rStr = Encoding.UTF8.GetString(tmp); T rObj = JsonConvert.DeserializeObject(rStr); if (rObj == null) { Logger.LogError("数据提交省统一平台失败,原因:{0}", "数据为空"); onFails(string.Format("数据提交省统一平台失败,原因:{0}", "数据为空")); return default(T); } return rObj; } /// /// POST 异步 /// /// /// /// /// /// async Task HttpGetAsync(string url, string formData, OnFails onFails) { HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Add("APIKey", "MUA5NmU3OTIxOEPSOFTDQ1YTMzMDExMg"); var r = await client.GetAsync(url + WebUtility.UrlEncode(formData)); if (r.StatusCode != HttpStatusCode.OK) { Logger.LogError("省统一平台异常反馈:状态“{0}”", r.StatusCode); onFails(string.Format("省统一平台异常反馈:状态“{0}”", r.StatusCode)); return default(T); } byte[] tmp = await r.Content.ReadAsByteArrayAsync(); string rStr = Encoding.UTF8.GetString(tmp); T rObj = JsonConvert.DeserializeObject(rStr); if (rObj == null) { Logger.LogError("数据提交省统一平台失败,原因:{0}", "数据为空"); onFails(string.Format("数据提交省统一平台失败,原因:{0}", "数据为空")); return default(T); } return rObj; } /// /// POST 同步 /// /// /// /// /// /// string HttpPost(string url, Dictionary formData = null, Encoding encoding = null, int timeOut = 10000) { HttpClientHandler handler = new HttpClientHandler(); HttpClient client = new HttpClient(handler); MemoryStream ms = new MemoryStream(); FillFormDataStream(formData, ms);//填充formData HttpContent hc = new StreamContent(ms); //client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html")); //client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xhtml+xml")); //client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml", 0.9)); //client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("image/webp")); //client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*", 0.8)); //hc.Headers.Add("UserAgent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"); //hc.Headers.Add("Timeout", timeOut.ToString()); //hc.Headers.Add("KeepAlive", "true"); var t = client.PostAsync(url, hc); t.Wait(); var t2 = t.Result.Content.ReadAsByteArrayAsync(); return encoding.GetString(t2.Result); } /// /// 组装QueryString的方法 /// 参数之间用&连接,首位没有符号,如:a=1&b=2&c=3 /// /// /// string GetQueryString(Dictionary formData) { if (formData == null || formData.Count == 0) { return ""; } StringBuilder sb = new StringBuilder(); var i = 0; foreach (var kv in formData) { i++; sb.AppendFormat("{0}={1}", kv.Key, kv.Value); if (i < formData.Count) { sb.Append("&"); } } return sb.ToString(); } /// /// 填充表单信息的Stream /// /// /// void FillFormDataStream(Dictionary formData, Stream stream) { string dataString = GetQueryString(formData); var formDataBytes = formData == null ? new byte[0] : Encoding.UTF8.GetBytes(dataString); stream.Write(formDataBytes, 0, formDataBytes.Length); stream.Seek(0, SeekOrigin.Begin);//设置指针读取位置 } } }