| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Net;
- using System.Text;
- using System.Xml;
- namespace TeamAAS_VP.Core.Sfis
- {
- public class SfisWebServiceClient
- {
- private readonly SfisConfig _config;
- private readonly object _invokeSync = new object();
- public event Action<string> OnLog;
- public bool IsLoggedIn { get; private set; }
- public SfisWebServiceClient(SfisConfig config)
- {
- _config = config ?? throw new ArgumentNullException(nameof(config));
- }
- public SfisResponse Login()
- {
- var response = Invoke("WTSP_LOGINOUT", new Dictionary<string, object>
- {
- { "programId", _config.ProgramId },
- { "programPassword", _config.ProgramPassword },
- { "op", _config.OperatorId },
- { "password", _config.OperatorPassword ?? string.Empty },
- { "device", _config.Device },
- { "TSP", _config.TspName },
- { "status", 1 }
- });
- if (response.IsSuccess)
- IsLoggedIn = true;
- return response;
- }
- public SfisResponse Logout()
- {
- var response = Invoke("WTSP_LOGINOUT", new Dictionary<string, object>
- {
- { "programId", _config.ProgramId },
- { "programPassword", _config.ProgramPassword },
- { "op", _config.OperatorId },
- { "password", _config.OperatorPassword ?? string.Empty },
- { "device", _config.Device },
- { "TSP", _config.TspName },
- { "status", 2 }
- });
- IsLoggedIn = false;
- return response;
- }
- public SfisResponse CheckRoute(string isn, int type, string checkFlag = null, string checkData = null)
- {
- return Invoke("WTSP_CHKROUTE", new Dictionary<string, object>
- {
- { "programId", _config.ProgramId },
- { "programPassword", _config.ProgramPassword },
- { "ISN", isn },
- { "device", _config.Device },
- { "checkFlag", checkFlag ?? string.Empty },
- { "checkData", checkData ?? string.Empty },
- { "type", type }
- });
- }
- public SfisResponse GetVersion(string isn, string type, string chkData = null, string chkData2 = null)
- {
- return Invoke("WTSP_GETVERSION", new Dictionary<string, object>
- {
- { "programId", _config.ProgramId },
- { "programPassword", _config.ProgramPassword },
- { "ISN", isn },
- { "device", _config.Device },
- { "type", type ?? string.Empty },
- { "ChkData", chkData ?? string.Empty },
- { "ChkData2", chkData2 ?? string.Empty }
- });
- }
- public SfisResponse SendResult(string isn, string data, int status, string errorCode = null)
- {
- return Invoke("WTSP_RESULT", new Dictionary<string, object>
- {
- { "programId", _config.ProgramId },
- { "programPassword", _config.ProgramPassword },
- { "ISN", isn },
- { "error", errorCode ?? string.Empty },
- { "device", _config.Device },
- { "TSP", _config.TspName },
- { "data", data },
- { "status", status },
- { "CPKFlag", string.Empty }
- });
- }
- public SfisResponse SendInputData(string data, int type)
- {
- return Invoke("WTSP_SSD_INPUTDATA", new Dictionary<string, object>
- {
- { "programId", _config.ProgramId },
- { "programPassword", _config.ProgramPassword },
- { "device", _config.Device },
- { "data", data },
- { "type", type }
- });
- }
- public SfisResponse Invoke(string methodName, IDictionary<string, object> parameters)
- {
- lock (_invokeSync)
- {
- if (_config.UseDryRun())
- return InvokeDryRun(methodName, parameters);
- ValidateLiveConfig();
- string soapAction = _config.SoapNamespace.TrimEnd('/') + "/" + methodName;
- string envelope = BuildSoapEnvelope(methodName, parameters);
- OnLog?.Invoke("SFIS 调用 " + methodName);
- var request = (HttpWebRequest)WebRequest.Create(_config.ServiceUrl);
- request.Method = "POST";
- request.ContentType = "text/xml; charset=utf-8";
- request.Headers.Add("SOAPAction", "\"" + soapAction + "\"");
- request.Timeout = _config.TimeoutMs;
- request.ReadWriteTimeout = _config.TimeoutMs;
- byte[] payload = Encoding.UTF8.GetBytes(envelope);
- request.ContentLength = payload.Length;
- using (var stream = request.GetRequestStream())
- stream.Write(payload, 0, payload.Length);
- try
- {
- using (var response = (HttpWebResponse)request.GetResponse())
- using (var reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
- {
- string soapResponse = reader.ReadToEnd();
- string result = ExtractSoapResult(soapResponse, methodName);
- var parsed = SfisResponse.Parse(result);
- OnLog?.Invoke("SFIS " + methodName + " => P_RET=" + parsed.ReturnCode);
- return parsed;
- }
- }
- catch (WebException ex)
- {
- string errorBody = ReadErrorBody(ex);
- OnLog?.Invoke("SFIS 调用失败: " + ex.Message);
- if (!string.IsNullOrWhiteSpace(errorBody))
- OnLog?.Invoke(errorBody);
- return new SfisResponse
- {
- ReturnCode = 0,
- Message = string.IsNullOrWhiteSpace(errorBody) ? ex.Message : errorBody,
- Raw = errorBody
- };
- }
- }
- }
- private void ValidateLiveConfig()
- {
- if (string.IsNullOrWhiteSpace(_config.ServiceUrl))
- throw new InvalidOperationException("SfisServiceUrl 未配置");
- if (string.IsNullOrWhiteSpace(_config.ProgramId))
- throw new InvalidOperationException("SfisProgramId 未配置");
- if (string.IsNullOrWhiteSpace(_config.Device))
- throw new InvalidOperationException("SfisDevice 未配置");
- }
- private static string ReadErrorBody(WebException ex)
- {
- if (ex.Response == null)
- return null;
- using (var reader = new StreamReader(ex.Response.GetResponseStream()))
- return reader.ReadToEnd();
- }
- private string BuildSoapEnvelope(string methodName, IDictionary<string, object> parameters)
- {
- var sb = new StringBuilder();
- sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
- sb.Append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">");
- sb.Append("<soap:Body>");
- sb.Append("<").Append(methodName).Append(" xmlns=\"").Append(XmlEscape(_config.SoapNamespace)).Append("\">");
- foreach (var pair in parameters)
- {
- sb.Append("<").Append(pair.Key).Append(">");
- sb.Append(XmlEscape(Convert.ToString(pair.Value ?? string.Empty)));
- sb.Append("</").Append(pair.Key).Append(">");
- }
- sb.Append("</").Append(methodName).Append(">");
- sb.Append("</soap:Body>");
- sb.Append("</soap:Envelope>");
- return sb.ToString();
- }
- private static string ExtractSoapResult(string soapResponse, string methodName)
- {
- if (string.IsNullOrWhiteSpace(soapResponse))
- return string.Empty;
- var doc = new XmlDocument();
- doc.LoadXml(soapResponse);
- string[] candidateNames = { methodName + "Result", methodName + "Response", "return" };
- foreach (string name in candidateNames)
- {
- XmlNodeList nodes = doc.GetElementsByTagName(name);
- if (nodes != null && nodes.Count > 0 && nodes[0] != null)
- return nodes[0].InnerText;
- }
- XmlNodeList bodyNodes = doc.GetElementsByTagName("soap:Body");
- if (bodyNodes == null || bodyNodes.Count == 0)
- bodyNodes = doc.GetElementsByTagName("Body");
- if (bodyNodes != null && bodyNodes.Count > 0 && bodyNodes[0] != null)
- return bodyNodes[0].InnerText?.Trim() ?? soapResponse;
- return soapResponse;
- }
- private SfisResponse InvokeDryRun(string methodName, IDictionary<string, object> parameters)
- {
- OnLog?.Invoke("[DryRun] SFIS 调用 " + methodName);
- switch (methodName)
- {
- case "WTSP_LOGINOUT":
- int status = Convert.ToInt32(parameters["status"]);
- if (status == 1)
- {
- IsLoggedIn = true;
- return SfisResponse.Parse("1" + SfisDelimiters.Field + "Welcome using Pegatron SFIS"
- + SfisDelimiters.Field + "DryRun Operator");
- }
- IsLoggedIn = false;
- return SfisResponse.Parse("1" + SfisDelimiters.Field + "Logout OK");
- case "WTSP_CHKROUTE":
- return SfisResponse.Parse("1" + SfisDelimiters.Field + "[#1][MODEL:DRYRUN]");
- case "WTSP_GETVERSION":
- return SfisResponse.Parse("1" + SfisDelimiters.Field + "DryRun Version");
- case "WTSP_RESULT":
- return SfisResponse.Parse("1" + SfisDelimiters.Field + "RESULT SAVED OK");
- case "WTSP_SSD_INPUTDATA":
- return SfisResponse.Parse("1" + SfisDelimiters.Field
- + "MO SAVED OK(DryRun);ISN OK!! PASS!-(TSP_SSD_INPUTDATA)");
- default:
- return SfisResponse.Parse("1" + SfisDelimiters.Field + methodName + " DryRun OK");
- }
- }
- private static string XmlEscape(string value)
- {
- if (string.IsNullOrEmpty(value))
- return string.Empty;
- return value.Replace("&", "&").Replace("<", "<").Replace(">", ">")
- .Replace("\"", """).Replace("'", "'");
- }
- }
- }
|