啊鑫
8 天以前 0aa54059b26e6641196e9953490dd18616e916e3
service/QC/OaApi.cs
@@ -1,35 +1,33 @@
// OaApiService.cs
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Data.SqlClient;
using System.Data;
using System.IO;
using System.Net.Http;
using System.Data.SqlClient;
using System.Dynamic;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using NewPdaSqlServer.entity.Base;
using NewPdaSqlServer.DB;
using NewPdaSqlServer.util;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using NewPdaSqlServer.DB;
using SqlSugar;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
using NewPdaSqlServer.entity;
using System.Linq;
namespace NewPdaSqlServer.service.QC;
public class OaApiService : Repository<dynamic>
{
    private readonly HttpClient _httpClient;
    //private const string AppId = "303233EF-AC39-40C1-8364-AC989C6258A5";
    //private const string BaseUrl = "http://192.168.1.149:8099/api/ec/dev/auth/";
    //private const string WorkflowUrl = "http://192.168.1.149:8099/api/workflow/paService/doCreateRequest";
    private const string AppId = "AB7F0461-89C3-4EAD-B5B5-B7D540617921";
    private const string BaseUrl = "http://192.168.1.20:80/api/ec/dev/auth/";
    private const string WorkflowUrl = "http://192.168.1.20:80/api/workflow/paService/doCreateRequest";
    private const string WorkflowUrl =
        "http://192.168.1.20:80/api/workflow/paService/doCreateRequest";
    private readonly HttpClient _httpClient;
    public OaApiService()
    {
@@ -37,11 +35,13 @@
        _httpClient.Timeout = TimeSpan.FromSeconds(30);
    }
    public  dynamic SubmitIQCToOA(dynamic queryObj)
    public dynamic SubmitIQCToOA(dynamic queryObj)
    {
        // 修改参数验证字段名
        if (string.IsNullOrEmpty(queryObj.userId.ToString())) throw new Exception("用户id不允许为空");
        if (string.IsNullOrEmpty(queryObj.qcczdGuid.ToString())) throw new Exception("异常处置单id不能为空");
        if (string.IsNullOrEmpty(queryObj.userId.ToString()))
            throw new Exception("用户id不允许为空");
        if (string.IsNullOrEmpty(queryObj.qcczdGuid.ToString()))
            throw new Exception("异常处置单id不能为空");
        //if (queryObj.qcczdGuid.IsNullOrEmpty()) throw new Exception("异常处置单id不能为空"); // 原参数名为 qcczdGuid
        try
@@ -51,31 +51,30 @@
            //var query = JObject.FromObject(queryObj);
            // 1. 注册获取凭证
            var registResult =  GetRegistAsync();
            var registResult = GetRegistAsync();
            var secret = registResult["secrit"].ToString();
            var spk = registResult["spk"].ToString();
            // 2. 获取访问令牌
            var tokenResult =  ApplyTokenAsync(secret, spk);
            var tokenResult = ApplyTokenAsync(secret, spk);
            var token = tokenResult["token"].ToString();
            string oaUserId = "";
            var oaUserId = "";
            using (var conn = new SqlConnection(DbHelperSQL.strConn))
            {
                using (var cmd = new SqlCommand("select_oa_userid", conn))
                {
                    try
                    {
                        conn.Open();
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.Add(new SqlParameter("@guid", SqlDbType.VarChar, 100) { Value = queryObj.qcczdGuid.ToString() });
                        cmd.Parameters.Add(
                            new SqlParameter("@guid", SqlDbType.VarChar, 100)
                                { Value = queryObj.qcczdGuid.ToString() });
                        using (var reader = cmd.ExecuteReader())
                        {
                            if (reader.Read())
                            {
                                oaUserId = reader["result"]?.ToString();
                            }
                        }
                    }
                    catch (Exception logEx)
@@ -93,7 +92,8 @@
            _httpClient.DefaultRequestHeaders.Clear();
            _httpClient.DefaultRequestHeaders.Add("token", token);
            _httpClient.DefaultRequestHeaders.Add("appid", AppId);
            _httpClient.DefaultRequestHeaders.Add("userid", RSAEncrypt(oaUserId, spk));
            _httpClient.DefaultRequestHeaders.Add("userid",
                RSAEncrypt(oaUserId, spk));
            // 4. 构建请求体
            var requestData = BuildRequestData(queryObj);
@@ -112,20 +112,34 @@
                    {
                        conn.Open();
                        cmd.CommandType = CommandType.StoredProcedure;
                        SqlParameter[] logParams =
                        SqlParameter[] logParams =
                        {
                            new("@edtUserGuid", SqlDbType.UniqueIdentifier) { Value = Guid.Parse(queryObj.userId.ToString()) },
                            new("@abtGuid", SqlDbType.UniqueIdentifier) { Value = Guid.Parse(queryObj.qcczdGuid.ToString()) },
                            new("@abtTable", SqlDbType.NVarChar, 40) { Value = "Mes_QC_Exceptional" },
                            new("@detail", SqlDbType.NVarChar, 2500) { Value = "提交IQC到OA系统" },
                            new("@edtUserGuid", SqlDbType.UniqueIdentifier)
                            {
                                Value = Guid.Parse(queryObj.userId.ToString())
                            },
                            new("@abtGuid", SqlDbType.UniqueIdentifier)
                            {
                                Value = Guid.Parse(
                                    queryObj.qcczdGuid.ToString())
                            },
                            new("@abtTable", SqlDbType.NVarChar, 40)
                                { Value = "Mes_QC_Exceptional" },
                            new("@detail", SqlDbType.NVarChar, 2500)
                                { Value = "提交IQC到OA系统" },
                            new("@hNo", SqlDbType.NVarChar, 100) { Value = "" },
                            new("@SendJson", SqlDbType.NVarChar) { Value = JObject.FromObject(requestData).ToString() },
                            new("@RtnJson", SqlDbType.NVarChar) { Value = response.Content.ToString() }
                            new("@SendJson", SqlDbType.NVarChar)
                            {
                                Value = JObject.FromObject(requestData)
                                    .ToString()
                            },
                            new("@RtnJson", SqlDbType.NVarChar)
                                { Value = response.Content.ToString() }
                        };
                        foreach (var param in logParams)
                            cmd.Parameters.Add(param);
                        cmd.ExecuteNonQuery();
                    }
                    catch (Exception logEx)
@@ -150,7 +164,7 @@
    checkDate   = GETDATE(),
    checkBy     = (select top 1 u.[ACCOUNT] from [dbo].[SYS_USER] u where u.guid = @edtUserCode)
WHERE GUID = @inOrderGuid";
                using (var conn = new SqlConnection(DbHelperSQL.strConn))
                {
                    using (var cmd = new SqlCommand(updateSql, conn))
@@ -159,8 +173,10 @@
                        {
                            conn.Open();
                            //cmd.Parameters.AddWithValue("@dt", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                            cmd.Parameters.AddWithValue("@edtUserCode", queryObj.userId?.ToString());
                            cmd.Parameters.AddWithValue("@inOrderGuid", queryObj.qcczdGuid?.ToString());
                            cmd.Parameters.AddWithValue("@edtUserCode",
                                queryObj.userId?.ToString());
                            cmd.Parameters.AddWithValue("@inOrderGuid",
                                queryObj.qcczdGuid?.ToString());
                            cmd.ExecuteNonQuery();
                        }
                        catch (Exception updateEx)
@@ -175,14 +191,13 @@
                }
            }
            return result;  // 直接解析为JObject
            return result; // 直接解析为JObject
        }
        catch (Exception ex)
        {
            dynamic error = new ExpandoObject();
            error.code = "SYSTEM_INNER_ERROR";  // 新增标准错误码
            error.errMsg = ex.Message;         // 修正字段名匹配规范
            error.code = "SYSTEM_INNER_ERROR"; // 新增标准错误码
            error.errMsg = ex.Message; // 修正字段名匹配规范
            error.data = new JObject();
            error.reqFailMsg = new JObject();
            return error;
@@ -194,11 +209,11 @@
        // 从query参数中获取实际业务数据
        return new Dictionary<string, object>
        {
            {"mainData", BuildMainData(queryObj)},
            {"requestName", $"IQC异常处置单流程-{DateTime.Now:yyyyMMddHHmmss}"},
            {"workflowId", "602"},//测试:379 正式:600->602
            { "mainData", BuildMainData(queryObj) },
            { "requestName", $"IQC异常处置单流程-{DateTime.Now:yyyyMMddHHmmss}" },
            { "workflowId", "602" }, //测试:379 正式:600->602
            //{"otherParams", BuildOtherParams()},
            {"detailData", BuildDetailData(queryObj)}
            { "detailData", BuildDetailData(queryObj) }
        };
    }
@@ -207,45 +222,45 @@
        var attachments = new JArray();
        foreach (var file in files ?? Enumerable.Empty<dynamic>())
        {
            attachments.Add(new JObject
            {
                // 修正字段名称匹配标准格式
                ["filePath"] = file.url?.ToString() ?? string.Empty,
                ["fileName"] = file.FileName?.ToString() ?? "未命名文件"
            });
        }
        return attachments;
    }
    private JArray BuildMainData(dynamic queryObj)
    {
        // 使用参数化查询防止SQL注入
        const string mainSql = @"EXEC select_oa_BuildMainData @guid";
        var mainData = Db.Ado.SqlQuery<dynamic>(mainSql, new { guid = queryObj.qcczdGuid });
        var mainData =
            Db.Ado.SqlQuery<dynamic>(mainSql,
                new { guid = queryObj.qcczdGuid });
        // 更精确的数据存在性检查
        if (mainData == null || !mainData.Any())
        {
            throw new Exception($"未找到异常处置单[{queryObj.qcczdGuid}]相关数据");
        }
        var firstRecord = mainData.First();
        // 字段映射配置(字段名 -> 数据库列名)
        var fieldMappings = new Dictionary<string, (string Field, string Default)>
        {
            ["sqr"] = ("sqr", "0"),       // 默认值改为数字
            ["sqrq"] = ("sqrq", ""),       // 空字符串用于日期格式化
            ["szbm"] = ("szbm", "0"),      // 默认值改为数字
            ["szdw"] = ("szdw", "0"),      // 默认值改为数字
            ["ycczdh"] = ("ycczdh", "N/A"),
            ["lh"] = ("lh", "N/A"),
            ["khgys"] = ("khgys", "N/A"),
            ["jzmcwlmc"] = ("jzmcwlmc", "N/A"),
            ["dhdhtxt"] = ("dhdhtxt", "N/A"),
            ["bhgpqxms"] = ("bhgpqxms", "无缺陷描述")
        };
        var fieldMappings =
            new Dictionary<string, (string Field, string Default)>
            {
                ["sqr"] = ("sqr", "0"), // 默认值改为数字
                ["sqrq"] = ("sqrq", ""), // 空字符串用于日期格式化
                ["szbm"] = ("szbm", "0"), // 默认值改为数字
                ["szdw"] = ("szdw", "0"), // 默认值改为数字
                ["ycczdh"] = ("ycczdh", "N/A"),
                ["lh"] = ("lh", "N/A"),
                ["khgys"] = ("khgys", "N/A"),
                ["jzmcwlmc"] = ("jzmcwlmc", "N/A"),
                ["dhdhtxt"] = ("dhdhtxt", "N/A"),
                ["bhgpqxms"] = ("bhgpqxms", "无缺陷描述")
            };
        // 动态生成字段集合
        var result = new JArray();
@@ -253,13 +268,19 @@
        {
            var value = mapping.Key switch
            {
                "sqr" or "szbm" or "szdw" =>
                    int.TryParse(GetDynamicValue(firstRecord, mapping.Value.Field, mapping.Value.Default), out int num)
                        ? num : 0,
                "sqrq" => DateTime.TryParse(GetDynamicValue(firstRecord, mapping.Value.Field, ""), out DateTime date)
                    ? date.ToString("yyyy-MM-dd")
                "sqr" or "szbm" or "szdw" =>
                    int.TryParse(
                        GetDynamicValue(firstRecord, mapping.Value.Field,
                            mapping.Value.Default), out int num)
                        ? num
                        : 0,
                "sqrq" => DateTime.TryParse(
                    GetDynamicValue(firstRecord, mapping.Value.Field, ""),
                    out DateTime date)
                    ? date.ToString("yyyy-MM-dd")
                    : DateTime.Now.ToString("yyyy-MM-dd"),
                _ => GetDynamicValue(firstRecord, mapping.Value.Field, mapping.Value.Default)
                _ => GetDynamicValue(firstRecord, mapping.Value.Field,
                    mapping.Value.Default)
            };
            result.Add(new JObject
            {
@@ -278,7 +299,9 @@
RIGHT JOIN MES_FILE C ON C.parent_Guid = B.guid
WHERE pGuid = @guid";
        var fileData = Db.Ado.SqlQuery<dynamic>(fileSql, new { guid = queryObj.qcczdGuid });
        var fileData =
            Db.Ado.SqlQuery<dynamic>(fileSql,
                new { guid = queryObj.qcczdGuid });
        var files = fileData.Count > 0 ? CreateFileData(fileData) : null; // 新增
        // 添加文件字段
@@ -292,11 +315,13 @@
    }
    // 辅助方法:安全获取dynamic对象值
    private static string GetDynamicValue(dynamic record, string field, string defaultValue)
    private static string GetDynamicValue(dynamic record, string field,
        string defaultValue)
    {
        try
        {
            return ((IDictionary<string, object>)record)[field]?.ToString() ?? defaultValue;
            return ((IDictionary<string, object>)record)[field]?.ToString() ??
                   defaultValue;
        }
        catch
        {
@@ -393,33 +418,33 @@
        var array = new JArray();
        if (attachments != null)
        {
            foreach (var att in attachments)
            {
                array.Add(new JObject
                {
                    ["filePath"] = att["url"]?.ToString(),
                    ["fileName"] = att["fileName"]?.ToString()
                });
            }
        }
        return array;
    }
    private JArray BuildDetailData(dynamic queryObj)
    {
        // 使用参数化查询获取明细数据
        const string mainSql = @"select ROW_NUMBER() over (ORDER BY Jy_Date) AS xh,releaseNo AS jydh, Jy_Date AS jydrq, batchQty as sjsl,
        const string mainSql =
            @"select ROW_NUMBER() over (ORDER BY Jy_Date) AS xh,releaseNo AS jydh, Jy_Date AS jydrq, batchQty as sjsl,
               chouQty AS cys, badQty AS bls, badProb AS bll,C.USER_NAME AS jyr
            from Mes_QC_Exceptional_Detail A
            LEFT JOIN MES_QA_ITEMS_DETECT_01 B ON A.releaseNo = B.release_no
            LEFT JOIN SYS_USER C ON C.ACCOUNT = B.fcheck_by
            WHERE pGuid = @guid";
        var details = Db.Ado.SqlQuery<dynamic>(mainSql, new { guid = queryObj.qcczdGuid });
        var details =
            Db.Ado.SqlQuery<dynamic>(mainSql,
                new { guid = queryObj.qcczdGuid });
        var tableRecords = new JArray();
        // 遍历每条明细数据
        foreach (var record in details ?? Enumerable.Empty<dynamic>())
        {
@@ -427,35 +452,58 @@
            var fields = new JArray
            {
                //new JObject { ["fieldName"] = "xh", ["fieldValue"] = record.xh?.ToString() ?? "" },
                new JObject { ["fieldName"] = "jydh", ["fieldValue"] = record.jydh?.ToString() ?? "" },
                 new JObject { ["fieldName"] = "jyr", ["fieldValue"] = record.jyr?.ToString() ?? "" },
                new JObject {
                    ["fieldName"] = "jydrq",
                new JObject
                {
                    ["fieldName"] = "jydh",
                    ["fieldValue"] = record.jydh?.ToString() ?? ""
                },
                new JObject
                {
                    ["fieldName"] = "jyr",
                    ["fieldValue"] = record.jyr?.ToString() ?? ""
                },
                new JObject
                {
                    ["fieldName"] = "jydrq",
                    // 格式化为"yyyy-MM-dd"字符串
                    ["fieldValue"] = (record.jydrq != null
                        ? Convert.ToDateTime(record.jydrq).ToString("yyyy-MM-dd ")
                        : DateTime.Now.ToString("yyyy-MM-dd"))
                    ["fieldValue"] = record.jydrq != null
                        ? Convert.ToDateTime(record.jydrq)
                            .ToString("yyyy-MM-dd ")
                        : DateTime.Now.ToString("yyyy-MM-dd")
                },
                // 数值字段保持数字类型而非字符串
                // 修正数值类型转换方式
                new JObject { ["fieldName"] = "sjsl", ["fieldValue"] = (float)(record.sjsl ?? 0m) },
                new JObject { ["fieldName"] = "cys", ["fieldValue"] = (float)(record.cys ?? 0) },
                new JObject { ["fieldName"] = "bls", ["fieldValue"] = (float)(record.bls ?? 0) },
                new JObject { ["fieldName"] = "bll", ["fieldValue"] = 1, }
                new JObject
                {
                    ["fieldName"] = "sjsl",
                    ["fieldValue"] = (float)(record.sjsl ?? 0m)
                },
                new JObject
                {
                    ["fieldName"] = "cys",
                    ["fieldValue"] = (float)(record.cys ?? 0)
                },
                new JObject
                {
                    ["fieldName"] = "bls",
                    ["fieldValue"] = (float)(record.bls ?? 0)
                },
                new JObject { ["fieldName"] = "bll", ["fieldValue"] = 1 }
            };
            tableRecords.Add(new JObject
            {
                ["recordOrder"] = 0,  // 实际业务中可能需要根据行号设置
                ["recordOrder"] = 0, // 实际业务中可能需要根据行号设置
                ["workflowRequestTableFields"] = fields
            });
        }
        return new JArray
        {
            new JObject
            {
                ["tableDBName"] = "formtable_main_321_dt1",//测试:formtable_main_33_dt1
                ["tableDBName"] =
                    "formtable_main_321_dt1", //测试:formtable_main_33_dt1
                ["workflowRequestTableRecords"] = tableRecords
            }
        };
@@ -470,7 +518,7 @@
        };
    }
    private  JObject GetRegistAsync()
    private JObject GetRegistAsync()
    {
        using var rsa = new RSACryptoServiceProvider(2048);
        var cpk = Convert.ToBase64String(rsa.ExportRSAPublicKey());
@@ -487,9 +535,11 @@
    {
        _httpClient.DefaultRequestHeaders.Clear();
        _httpClient.DefaultRequestHeaders.Add("appid", AppId);
        _httpClient.DefaultRequestHeaders.Add("secret", RSAEncrypt(secret, spk));
        _httpClient.DefaultRequestHeaders.Add("secret",
            RSAEncrypt(secret, spk));
        var response = _httpClient.PostAsync(BaseUrl + "applytoken", null).Result;
        var response =
            _httpClient.PostAsync(BaseUrl + "applytoken", null).Result;
        return JObject.Parse(response.Content.ReadAsStringAsync().Result);
    }
@@ -501,17 +551,24 @@
        //var dataBytes = Encoding.UTF8.GetBytes(data);
        //var encrypted = rsa.Encrypt(dataBytes, RSAEncryptionPadding.Pkcs1);
        //return Convert.ToBase64String(encrypted);
        RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
        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())
        var publicKeyParam =
            (RsaKeyParameters)PublicKeyFactory.CreateKey(
                Convert.FromBase64String(publicKey));
        var XML = string.Format(
            "<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
            Convert.ToBase64String(publicKeyParam.Modulus
                .ToByteArrayUnsigned()),
            Convert.ToBase64String(
                publicKeyParam.Exponent.ToByteArrayUnsigned()));
        var encryptedContent = string.Empty;
        using (var rsa = new RSACryptoServiceProvider())
        {
            rsa.FromXmlString(XML);
            byte[] encryptedData = rsa.Encrypt(Encoding.Default.GetBytes(data), false);
            var encryptedData =
                rsa.Encrypt(Encoding.Default.GetBytes(data), false);
            encryptedContent = Convert.ToBase64String(encryptedData);
        }
        return encryptedContent;
    }
@@ -520,12 +577,13 @@
        // 改用FormUrlEncodedContent并正确设置Content-Type
        var formData = new List<KeyValuePair<string, string>>();
        foreach (var item in data)
        {
            formData.Add(new KeyValuePair<string, string>(item.Key, item.Value.ToString()));
        }
            formData.Add(
                new KeyValuePair<string, string>(item.Key,
                    item.Value.ToString()));
        var content = new FormUrlEncodedContent(formData);
        content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");
        content.Headers.ContentType =
            new MediaTypeHeaderValue("application/x-www-form-urlencoded");
        var response = _httpClient.PostAsync(url, content).Result;
        var responseString = response.Content.ReadAsStringAsync().Result;
@@ -540,7 +598,8 @@
        };
        // 调试输出完整响应信息
        Console.WriteLine($"完整响应:\n{responseInfo.ToString(Formatting.Indented)}");
        Console.WriteLine(
            $"完整响应:\n{responseInfo.ToString(Formatting.Indented)}");
        return responseInfo;
    }
@@ -549,4 +608,4 @@
    {
        _httpClient?.Dispose();
    }
}
}