南骏 池
2025-05-12 c418ccde908642c73f86ff43cc999be835a1e77d
service/QC/OAJyService.cs
@@ -11,6 +11,13 @@
using System.Security.Cryptography;
using System.Text;
using static Azure.Core.HttpHeader;
using System.Security.Cryptography;
using System.Collections.Generic;
using System.Linq;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace NewPdaSqlServer.service.QC;
@@ -23,34 +30,39 @@
    // private const string SPK = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApobID/gwmD9OofMG1gEcE94NCMeTYUq1cam/7ADZmxHCVpF143GaHWhqDdY0TTVbcUElsQ71DzAG2j3itWlIJBK5fVGwCo3sPpAvUDdKMh+Uivcp7yxdy/IDRA/PS4JARuEyM4cVJLhIOU2KnSlbIkheeoDkDgfaxu9kKrWnozJLiYraVTVDz9PdRX7fQdP+Zu/xB9txAGw4kvOm9HwgrzaSRdZEhisTJ5yyoNW/dLXtWKXA0cKhKOOIFu12TOrv/It6hl1ShTUuy79Pa51M9Oc2dEfVs1tluNXPWo1uFXQbBaJxdqZEJJlK7iW2uQFIao2O4XFHYThwy2+6116LtwIDAQAB";
    private const string HOST = "http://192.168.1.149:8099";
    private const string SPK = @"-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApobID/gwmD9OofMG1gEc
E94NCMeTYUq1cam/7ADZmxHCVpF143GaHWhqDdY0TTVbcUElsQ71DzAG2j3itWlI
JBK5fVGwCo3sPpAvUDdKMh+Uivcp7yxdy/IDRA/PS4JARuEyM4cVJLhIOU2KnSlb
IkheeoDkDgfaxu9kKrWnozJLiYraVTVDz9PdRX7fQdP+Zu/xB9txAGw4kvOm9Hwg
rzaSRdZEhisTJ5yyoNW/dLXtWKXA0cKhKOOIFu12TOrv/It6hl1ShTUuy79Pa51M
9Oc2dEfVs1tluNXPWo1uFXQbBaJxdqZEJJlK7iW2uQFIao2O4XFHYThwy2+6116L
twIDAQAB
-----END PUBLIC KEY-----";
    private const string SPK = @"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApobID/gwmD9OofMG1gEcE94NCMeTYUq1cam/7ADZmxHCVpF143GaHWhqDdY0TTVbcUElsQ71DzAG2j3itWlIJBK5fVGwCo3sPpAvUDdKMh+Uivcp7yxdy/IDRA/PS4JARuEyM4cVJLhIOU2KnSlbIkheeoDkDgfaxu9kKrWnozJLiYraVTVDz9PdRX7fQdP+Zu/xB9txAGw4kvOm9HwgrzaSRdZEhisTJ5yyoNW/dLXtWKXA0cKhKOOIFu12TOrv/It6hl1ShTUuy79Pa51M9Oc2dEfVs1tluNXPWo1uFXQbBaJxdqZEJJlK7iW2uQFIao2O4XFHYThwy2+6116LtwIDAQAB";
    public static class RsaHelper
    {
        public static string Encrypt(string plainText, string publicKeyPem)
        {
            // 将PEM格式的公钥转换为XML格式
            var rsa = RSA.Create();
            rsa.ImportFromPem(publicKeyPem);  // 使用.NET 5+ 内置PEM解析方法
            //// 将PEM格式的公钥转换为XML格式
            //var rsa = RSA.Create();
            //rsa.ImportFromPem(publicKeyPem);  // 使用.NET 5+ 内置PEM解析方法
            var parameters = rsa.ExportParameters(false);
            string publicKeyXml = $"<RSAKeyValue><Modulus>{Convert.ToBase64String(parameters.Modulus)}</Modulus><Exponent>{Convert.ToBase64String(parameters.Exponent)}</Exponent></RSAKeyValue>";
            //var parameters = rsa.ExportParameters(false);
            //string publicKeyXml = $"<RSAKeyValue><Modulus>{Convert.ToBase64String(parameters.Modulus)}</Modulus><Exponent>{Convert.ToBase64String(parameters.Exponent)}</Exponent></RSAKeyValue>";
            using var rsaProvider = new RSACryptoServiceProvider();
            rsaProvider.FromXmlString(publicKeyXml);  // 使用转换后的XML格式公钥
            //using var rsaProvider = new RSACryptoServiceProvider();
            //rsaProvider.FromXmlString(publicKeyXml);  // 使用转换后的XML格式公钥
            var data = Encoding.UTF8.GetBytes(plainText);
            var encrypted = rsaProvider.Encrypt(data, false);
            return Convert.ToBase64String(encrypted);
            //var data = Encoding.UTF8.GetBytes(plainText);
            //var encrypted = rsaProvider.Encrypt(data, false);
            //return Convert.ToBase64String(encrypted);
            RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKeyPem));
            string XML = string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
            Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
            Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
            string encryptedContent = string.Empty;
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                rsa.FromXmlString(XML);
                byte[] encryptedData = rsa.Encrypt(Encoding.Default.GetBytes(plainText), false);
                encryptedContent = Convert.ToBase64String(encryptedData);
            }
            return encryptedContent;
        }
    }
@@ -78,12 +90,14 @@
    public string GetToken()
    {
;
        var userId = "1268";
        var encryptedUserId = RsaHelper.Encrypt(userId, SPK);
        ;
        var headers = new Dictionary<string, string>
        {
            ["appid"] = APPID,
            ["secret"] = RsaHelper.Encrypt(SECRET, SPK)
            ["secret"] = RsaHelper.Encrypt(SECRET, SPK),
            ["userId"] = encryptedUserId
        };
        try
@@ -109,130 +123,251 @@
    }
    public string GetOaKqInfo(Uri url, string token, string userId)
    //public string GetOaKqInfo(Uri url, string token, string userId)
    //{
    //    try
    //    {
    //        ServicePointManager.ServerCertificateValidationCallback += (s, cert, chain, sslPolicyErrors) => true;
    //        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    //        var request = WebRequest.Create(url) as HttpWebRequest;
    //        request.Method = "POST";
    //        request.Timeout = 20000;  // 20秒超时
    //        request.ContentType = "application/x-www-form-urlencoded; charset=utf-8";  // 明确指定编码
    //        // 添加调试头信息
    //        request.Headers.Add("appid", APPID);
    //        request.Headers.Add("token", token);
    //        request.Headers.Add("userId", userId);
    //        // 构建带时区的日期参数
    //        var postData = new StringBuilder();
    //        var dateParam = DateTime.Now.AddDays(-1).ToString("yyyy-MM-ddTHH:mm:sszzz");
    //        postData.AppendFormat("KQSDATE={0}&KQEDATE={1}",
    //            Uri.EscapeDataString(dateParam),
    //            Uri.EscapeDataString(dateParam));
    //        byte[] byteData = Encoding.UTF8.GetBytes(postData.ToString());  // 改用UTF8编码
    //        // 更完善的请求写入
    //        using (var stream = request.GetRequestStream())
    //        {
    //            stream.Write(byteData, 0, byteData.Length);
    //        }
    //        // 处理HTTP错误状态码
    //        using (var response = request.GetResponse() as HttpWebResponse)
    //        {
    //            if (response.StatusCode != HttpStatusCode.OK)
    //            {
    //                throw new WebException($"服务器返回错误状态码: {(int)response.StatusCode} {response.StatusDescription}");
    //            }
    //            using (var stream = response.GetResponseStream())
    //            using (var reader = new StreamReader(stream, Encoding.UTF8))
    //            {
    //                return reader.ReadToEnd();
    //            }
    //        }
    //    }
    //    catch (WebException ex) when (ex.Response is HttpWebResponse response)
    //    {
    //        // 记录详细错误信息
    //        var errorStream = response.GetResponseStream();
    //        using (var reader = new StreamReader(errorStream))
    //        {
    //            string errorDetails = reader.ReadToEnd();
    //            throw new Exception($"请求失败 [Status: {response.StatusCode}]: {errorDetails}", ex);
    //        }
    //    }
    //    catch (Exception ex)
    //    {
    //        throw new Exception($"请求异常: {ex.Message}", ex);
    //    }
    //}
    public dynamic SubmitIQCToOA(dynamic query)
    {
        try
        {
            // 参数校验
            if (query == null) throw new ArgumentNullException(nameof(query), "参数对象不能为null");
            //if (query.workflowId == null) throw new ArgumentException("workflowId不能为空");
            //if (query.mainData == null) throw new ArgumentException("mainData不能为空");
            // 转换动态参数
            //var mainDataDict = ((IEnumerable<KeyValuePair<string, object>>)query.mainData)
            //    .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
            Dictionary<string, object> mainDataDict = null;
            Dictionary<string, object> detailDataDict = null;
            //if (query.detailData != null)
            //{
            //    detailDataDict = ((IEnumerable<KeyValuePair<string, object>>)query.detailData)
            //        .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
            //}
            // 加密处理
            var userId = "1268";
            var encryptedUserId = RsaHelper.Encrypt(userId, SPK);
            string strToken = GetToken();
            // 替换原有的测mainDataDict试数据构建
            mainDataDict = BuildMainDataFromQuery(query);
            // 调用方法增加userid请求头
            var result = SubmitWorkflowRequest(
                token: strToken,
                workflowId: 379,
                mainData: mainDataDict,
                requestName: "MES->OA测试流程标题",
                otherParams:null,
                remark:"Test",
                requestLevel:"",
                encryptedUserId: encryptedUserId  // 新增参数
            );
            return result;
        }
        catch (Exception ex)
        {
            // 更详细的错误处理
            return new {
                status = -1,
                message = $"完整错误信息:{ex.ToString()}"  // 显示完整堆栈
            };
        }
    }
    // 修改方法签名
    public dynamic SubmitWorkflowRequest(
        string token,
        int workflowId,
        Dictionary<string, object> mainData,
        string encryptedUserId,  // 用户id
        Dictionary<string, object> detailData = null,
        Dictionary<string, object> otherParams = null,
        string remark = "",
        string requestLevel = "",
        string requestName = "默认流程标题")
    {
        try
        {
            ServicePointManager.ServerCertificateValidationCallback += (s, cert, chain, sslPolicyErrors) => true;
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            var url = new Uri($"{HOST}/api/workflow/paService/doCreateRequest");
            var request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "POST";
            request.Timeout = 20000;  // 20秒超时
            request.ContentType = "application/x-www-form-urlencoded; charset=utf-8";  // 明确指定编码
            request.Timeout = 20000;
            request.ContentType = "application/x-www-form-urlencoded";  // 修改为JSON格式
            // 添加调试头信息
            request.Headers.Add("appid", APPID);
            request.Headers.Add("token", token);
            request.Headers.Add("userId", userId);
            // 构建请求头
            request.Headers.Set("appid", APPID);
            request.Headers.Set("token", token);
            request.Headers.Set("Content-Type", "application/x-www-form-urlencoded");
            request.Headers.Set("userId", encryptedUserId);
            // 假设需要加密的userid从其他地方获取,这里需要补充获取逻辑
            // 构建带时区的日期参数
            var postData = new StringBuilder();
            var dateParam = DateTime.Now.AddDays(-1).ToString("yyyy-MM-ddTHH:mm:sszzz");
            postData.AppendFormat("KQSDATE={0}&KQEDATE={1}",
                Uri.EscapeDataString(dateParam),
                Uri.EscapeDataString(dateParam));
            // 构建请求体
            var requestBody = new Dictionary<string, object>
            {
                //["userId"] = "1268",
                ["workflowId"] = workflowId,
                ["mainData"] = new List<Dictionary<string, object>> { mainData }, // 包装成数组
                ["detailData"] = null,
                ["otherParams"] = otherParams ?? new Dictionary<string, object>(),
                ["remark"] = remark,
                ["requestLevel"] = requestLevel,
                ["requestName"] = requestName
            };
            byte[] byteData = Encoding.UTF8.GetBytes(postData.ToString());  // 改用UTF8编码
            // 序列化请求体
            var jsonBody = JsonConvert.SerializeObject(requestBody);
            byte[] byteData = Encoding.UTF8.GetBytes(jsonBody);
            // 更完善的请求写入
            // 发送请求
            using (var stream = request.GetRequestStream())
            {
                stream.Write(byteData, 0, byteData.Length);
            }
            // 处理HTTP错误状态码
            // 处理响应
            using (var response = request.GetResponse() as HttpWebResponse)
            {
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    throw new WebException($"服务器返回错误状态码: {(int)response.StatusCode} {response.StatusDescription}");
                }
                using (var stream = response.GetResponseStream())
                using (var reader = new StreamReader(stream, Encoding.UTF8))
                {
                    return reader.ReadToEnd();
                    var responseJson = reader.ReadToEnd();
                    var result = JsonConvert.DeserializeObject<dynamic>(responseJson);
                    // 添加状态码检查
                    if (response.StatusCode != HttpStatusCode.OK || result.code != "SUCCESS")
                    {
                        throw new Exception($"流程提交失败:{result.errMsg}");
                    }
                    return new
                    {
                        code = result.code,
                        data = result.data,
                        errMsg = result.errMsg
                    };
                }
            }
        }
        catch (WebException ex) when (ex.Response is HttpWebResponse response)
        {
            // 记录详细错误信息
            var errorStream = response.GetResponseStream();
            using (var reader = new StreamReader(errorStream))
            using (var stream = response.GetResponseStream())
            using (var reader = new StreamReader(stream))
            {
                string errorDetails = reader.ReadToEnd();
                throw new Exception($"请求失败 [Status: {response.StatusCode}]: {errorDetails}", ex);
                var errorDetails = reader.ReadToEnd();
                throw new Exception($"请求失败 [Status: {response.StatusCode}]: {errorDetails}");
            }
        }
        catch (Exception ex)
        {
            throw new Exception($"请求异常: {ex.Message}", ex);
            throw new Exception($"流程提交异常: {ex.Message}");
        }
    }
    public dynamic SumbitIQCToOA(dynamic queryObj)
    // 新增的构建方法
    private Dictionary<string, object> BuildMainDataFromQuery(dynamic query)
    {
        try
        var mainData = new Dictionary<string, object>
        {
            ServicePointManager.ServerCertificateValidationCallback += (s, cert, chain, sslPolicyErrors) => true;
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            var request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "POST";
            request.Timeout = 20000;  // 20秒超时
            request.ContentType = "application/x-www-form-urlencoded; charset=utf-8";  // 明确指定编码
            // 添加调试头信息
            request.Headers.Add("appid", APPID);
            request.Headers.Add("token", token);
            request.Headers.Add("userId", userId);
            // 构建带时区的日期参数
            var postData = new StringBuilder();
            var dateParam = DateTime.Now.AddDays(-1).ToString("yyyy-MM-ddTHH:mm:sszzz");
            postData.AppendFormat("KQSDATE={0}&KQEDATE={1}",
                Uri.EscapeDataString(dateParam),
                Uri.EscapeDataString(dateParam));
            byte[] byteData = Encoding.UTF8.GetBytes(postData.ToString());  // 改用UTF8编码
            // 更完善的请求写入
            using (var stream = request.GetRequestStream())
            // 表结构定义
            ["tableDBName"] = "formtable_main_33",
            ["workflowRequestTableRecords"] = new List<Dictionary<string, object>>
            {
                stream.Write(byteData, 0, byteData.Length);
            }
            // 处理HTTP错误状态码
            using (var response = request.GetResponse() as HttpWebResponse)
            {
                if (response.StatusCode != HttpStatusCode.OK)
                new Dictionary<string, object>
                {
                    throw new WebException($"服务器返回错误状态码: {(int)response.StatusCode} {response.StatusDescription}");
                }
                using (var stream = response.GetResponseStream())
                using (var reader = new StreamReader(stream, Encoding.UTF8))
                {
                    return reader.ReadToEnd();
                    ["recordOrder"] = 0,
                    ["workflowRequestTableFields"] = new List<Dictionary<string, object>>
                    {
                        new Dictionary<string, object> { ["fieldName"] = "wlbm", ["fieldValue"] = "1.01.01.001" },
                        new Dictionary<string, object> { ["fieldName"] = "khgys", ["fieldValue"] = "陈雪年" },
                        new Dictionary<string, object> { ["fieldName"] = "jzmcwlmc", ["fieldValue"] = "顶盖" },
                        new Dictionary<string, object> { ["fieldName"] = "bhgpqxms", ["fieldValue"] = "外观不合格,尺寸不合格,颜色不符合" },
                        new Dictionary<string, object> { ["fieldName"] = "dhdhmes", ["fieldValue"] = "MES001" }
                    }
                }
            }
        }
        catch (WebException ex) when (ex.Response is HttpWebResponse response)
        };
        return mainData;
    }
    // 辅助方法用于安全添加属性
    private void TryAddProperty(Dictionary<string, object> dict, string key, object value)
    {
        if (value != null)
        {
            // 记录详细错误信息
            var errorStream = response.GetResponseStream();
            using (var reader = new StreamReader(errorStream))
            {
                string errorDetails = reader.ReadToEnd();
                throw new Exception($"请求失败 [Status: {response.StatusCode}]: {errorDetails}", ex);
            }
        }
        catch (Exception ex)
        {
            throw new Exception($"请求异常: {ex.Message}", ex);
            dict[key] = value;
        }
    }
}