CrazyIter_Bin 6 miesięcy temu
rodzic
commit
a1c3b80f77

+ 173 - 0
TEAMModelOS/Controllers/Third/XunFeiJYY/XunFeiJYYService.cs

@@ -0,0 +1,173 @@
+using System.Security.Cryptography;
+using System;
+using System.Text;
+using System.Net;
+using System.Collections.Generic;
+using System.IO;
+using System.Net.Http;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK;
+
+namespace TEAMModelOS.Controllers.Third.XunFeiJYY
+{
+    public static class XunFeiJYYService
+    {
+
+        /// <summary>
+        /// 编码格式 UTF-8
+        /// </summary>
+        public static Encoding encoding = new UTF8Encoding();
+        /// <summary>
+        /// 应用id,应用的唯一标识
+        /// </summary>
+        private static string authAppId = "ea4e44e1dea54caba7b06bdea72970fa";
+        /// <summary>
+        /// 签名计算密钥
+        /// </summary>
+        private static string authAppSecret = "bb79a189fb9c22e9ae1a62b279a112c0";
+        /// <summary>
+        /// 请求的地址
+        /// </summary>
+        private static string host = "https://open.jyyun.com";
+        /// <summary>
+        /// 端口
+        /// </summary>
+        //private static int port = 80;
+
+        /// <summary>
+        /// 开始POST请求
+        /// </summary>
+        /// <param name="apiName">具体请求的接口</param>
+        /// <param name="paramsDic">参数的字典</param>
+        /// <returns></returns>
+        private static async Task<string> PostRequest(HttpClient httpClient,  string apiName, Dictionary<string, string> paramsDic)
+        {
+            string result = "";
+            string content = BuildParams(paramsDic);
+            var url = $"{host}/{apiName}";
+            SetHeader(httpClient, apiName + content);
+            var response = await httpClient.PostAsync(url, new StringContent($"schoolId=fbc284072a40da841b643aa367013eb18a1d351ed46b0feb15f629530e2f3c1137ae30823af5c69d3b88ef0fa3c761efee102032fc5d2a5a", Encoding.UTF8, "application/x-www-form-urlencoded"));
+            if (response.IsSuccessStatusCode)
+            {
+                result= await response.Content.ReadAsStringAsync();
+            }
+            else
+            {
+                return "接口请求失败,状态码:" + (int)response.StatusCode + response.StatusCode;
+            }
+            return result;
+        }
+
+ 
+
+        /// <summary>
+        /// 生成加密密钥密文
+        /// </summary>
+        /// <param name="url">端口后的部分,如果请求包含query参数,需要拼接成 path?k1=v1的形式 例:url = "/deploytest?aaa=test"</param>
+        /// <param name="authRandomKey">加密传输时才需要,目前传null</param>
+        /// <param name="authNonce">生成的uuid</param>
+        /// <param name="authTimestamp">当前的时间戳13位</param>
+        /// <param name="contentMD5">有请求体时才传,当前传null</param>
+        /// <returns>加密后的字符串</returns>
+        private static string GetSign(string url, string authRandomKey, string authNonce, string authTimestamp, string contentMD5)
+        {
+            StringBuilder sb = new StringBuilder();
+            AppendStr(sb, url);
+            AppendStr(sb, authRandomKey);
+            AppendStr(sb, authNonce);
+            AppendStr(sb, authTimestamp);
+            AppendStr(sb, authAppId);
+            AppendStr(sb, contentMD5);
+            var stingToSign = sb.ToString();
+            //去掉最后一个|
+            stingToSign = stingToSign.Substring(0, stingToSign.Length-1);
+            byte[] keyByte = encoding.GetBytes(authAppSecret);
+            byte[] messageBytes = encoding.GetBytes(stingToSign);
+            using (var hmacsha256 = new HMACSHA256(keyByte))
+            {
+                byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
+                return Convert.ToBase64String(hashmessage);
+            }
+        }
+        /// <summary>
+        /// 如果传入参数不为空 加入到StringBuilder中
+        /// </summary>
+        /// <param name="sb"></param>
+        /// <param name="str"></param>
+        private static void AppendStr(StringBuilder sb, string str)
+        {
+            if (!string.IsNullOrEmpty(str))
+            {
+                sb.Append(str + "|");
+            }
+        }
+
+        
+        /// <summary>
+        /// 设置请求的头
+        /// </summary>
+        /// <param name="request">根据地址生成的请求</param>
+        /// <param name="url">调用的具体的接口已经传入的参数</param>
+        private static void SetHeader(HttpClient client , string url)
+        {
+            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
+            var authTimestamp = Convert.ToInt64(ts.TotalMilliseconds).ToString();
+            String authNonce = Guid.NewGuid().ToString();
+            // 默认RELEASE
+            client.DefaultRequestHeaders.Add("S-Auth-Stage", "RELEASE");
+            // 应用id,创建应用时分配的,可在应用管理中的概况获取
+            client.DefaultRequestHeaders.Add("S-Auth-AppId", authAppId);
+            client.DefaultRequestHeaders.Add("S-Auth-Timestamp", authTimestamp);
+            client.DefaultRequestHeaders.Add("S-Auth-Nonce", authNonce);
+            // 默认 1
+            client.DefaultRequestHeaders.Add("S-Auth-Version", "1");
+            // 请求签名 
+            String sign = GetSign(url, "", authNonce, authTimestamp, null);
+            client.DefaultRequestHeaders.Add("S-Auth-Signature", sign);
+        }
+
+
+        
+        /// <summary>
+        /// 生成要传入的参数的字符串 格式:?key1=value1&key2=value2
+        /// </summary>
+        /// <param name="paramsDic"></param>
+        /// <returns>以问号开头的参数列</returns>
+        private static string BuildParams(Dictionary<String, String> paramsDic)
+        {
+            if (paramsDic.Count != 0)
+            {
+                StringBuilder sb = new StringBuilder();
+                sb.Append("?");
+                foreach (var item in paramsDic)
+                {
+                    sb.Append(item.Key + "=" + item.Value);
+                    sb.Append("&");
+                }
+                return sb.ToString().TrimEnd('&');
+            }
+            return "";
+        }
+        /// <summary>
+        /// 开始请求
+        /// </summary>
+        /// <param name="httpMethod">请求的方法 GET POST..</param>
+        /// <param name="apiName">具体请求的接口</param>
+        /// <param name="paramsDic">参数的字典</param>
+        /// <returns></returns>
+        public static async Task<string> Request(HttpClient httpClient, string httpMethod,string apiName, Dictionary<string, string> paramsDic)
+        {
+            switch (httpMethod.ToUpper())
+            {
+                case "POST":
+                    return await PostRequest(httpClient,apiName, paramsDic);
+                case "GET":
+                    break;
+                  //  return GetRequest(apiName, paramsDic);
+                default:
+                    break;
+            }
+            return "";
+        }
+    }
+}

+ 196 - 0
TEAMModelOS/Controllers/Third/XunFeiJYY/XunFeiService.cs

@@ -0,0 +1,196 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Security.Cryptography;
+using System.Text;
+using System;
+
+namespace TEAMModelOS.Controllers.Third.XunFeiJYY
+{
+    public class XunFeiService
+    {
+        /// <summary>
+        /// 编码格式 UTF-8
+        /// </summary>
+        public static Encoding encoding = new UTF8Encoding();
+        /// <summary>
+        /// 应用id,应用的唯一标识
+        /// </summary>
+        private static String authAppId = "ea4e44e1dea54caba7b06bdea72970fa";
+        /// <summary>
+        /// 签名计算密钥
+        /// </summary>
+        private static String authAppSecret = "bb79a189fb9c22e9ae1a62b279a112c0";
+        /// <summary>
+        /// 请求的地址
+        /// </summary>
+        private static String host = "https://open.jyyun.com";
+        /// <summary>
+        /// 端口
+        /// </summary>
+        private static int port = 443;
+
+        /// <summary>
+        /// 生成加密密钥密文
+        /// </summary>
+        /// <param name="url">端口后的部分,如果请求包含query参数,需要拼接成 path?k1=v1的形式 例:url = "/deploytest?aaa=test"</param>
+        /// <param name="authRandomKey">加密传输时才需要,目前传null</param>
+        /// <param name="authNonce">生成的uuid</param>
+        /// <param name="authTimestamp">当前的时间戳13位</param>
+        /// <param name="contentMD5">有请求体时才传,当前传null</param>
+        /// <returns>加密后的字符串</returns>
+        private static string GetSign(string url, string authRandomKey, string authNonce, string authTimestamp, string contentMD5)
+        {
+            StringBuilder sb = new StringBuilder();
+            AppendStr(sb, url);
+            AppendStr(sb, authRandomKey);
+            AppendStr(sb, authNonce);
+            AppendStr(sb, authTimestamp);
+            AppendStr(sb, authAppId);
+            AppendStr(sb, contentMD5);
+            var stingToSign = sb.ToString();
+            //去掉最后一个|
+            stingToSign = stingToSign.Substring(0, stingToSign.Length-1);
+            byte[] keyByte = encoding.GetBytes(authAppSecret);
+            byte[] messageBytes = encoding.GetBytes(stingToSign);
+            using (var hmacsha256 = new HMACSHA256(keyByte))
+            {
+                byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
+                return Convert.ToBase64String(hashmessage);
+            }
+        }
+
+        /// <summary>
+        /// 如果传入参数不为空 加入到StringBuilder中
+        /// </summary>
+        /// <param name="sb"></param>
+        /// <param name="str"></param>
+        private static void AppendStr(StringBuilder sb, string str)
+        {
+            if (!string.IsNullOrEmpty(str))
+            {
+                sb.Append(str + "|");
+            }
+        }
+
+        /// <summary>
+        /// 设置请求的头
+        /// </summary>
+        /// <param name="request">根据地址生成的请求</param>
+        /// <param name="url">调用的具体的接口已经传入的参数</param>
+        private static void SetHeader(HttpWebRequest request, string url)
+        {
+            request.Accept = "application/json";
+            request.ContentType = "application/json; charset=UTF-8";
+            TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
+            var authTimestamp = Convert.ToInt64(ts.TotalMilliseconds).ToString();
+            String authNonce = Guid.NewGuid().ToString();
+            // 默认RELEASE
+            request.Headers.Add("S-Auth-Stage", "RELEASE");
+            // 应用id,创建应用时分配的,可在应用管理中的概况获取
+            request.Headers.Add("S-Auth-AppId", authAppId);
+            request.Headers.Add("S-Auth-Timestamp", authTimestamp);
+            request.Headers.Add("S-Auth-Nonce", authNonce);
+            // 默认 1
+            request.Headers.Add("S-Auth-Version", "1");
+            // 请求签名 
+            String sign = GetSign(url, "", authNonce, authTimestamp, null);
+            request.Headers.Add("S-Auth-Signature", sign);
+        }
+
+        /// <summary>
+        /// 生成要传入的参数的字符串 格式:?key1=value1&key2=value2
+        /// </summary>
+        /// <param name="paramsDic"></param>
+        /// <returns>以问号开头的参数列</returns>
+        private static string BuildParams(Dictionary<String, String> paramsDic)
+        {
+            if (paramsDic.Count != 0)
+            {
+                StringBuilder sb = new StringBuilder();
+                sb.Append("?");
+                foreach (var item in paramsDic)
+                {
+                    //sb.Append($"{item.Key}={item.Value}");
+                    sb.Append(item.Key + "=" + item.Value);
+                    sb.Append("&");
+                }
+                return sb.ToString().TrimEnd('&');
+            }
+            return "";
+        }
+
+        /// <summary>
+        /// 开始请求
+        /// </summary>
+        /// <param name="httpMethod">请求的方法 GET POST..</param>
+        /// <param name="apiName">具体请求的接口</param>
+        /// <param name="paramsDic">参数的字典</param>
+        /// <returns></returns>
+        public static string Request(String httpMethod, String apiName, Dictionary<String, String> paramsDic)
+        {
+            switch (httpMethod.ToUpper())
+            {
+                case "POST":
+                    return PostRequest(apiName, paramsDic);
+                case "GET":
+                    return GetRequest(apiName, paramsDic);
+                default:
+                    break;
+            }
+            return "";
+        }
+
+        /// <summary>
+        /// 开始GET请求 暂时没有GET方法
+        /// </summary>
+        /// <param name="apiName"></param>
+        /// <param name="paramsDic"></param>
+        /// <returns></returns>
+        private static string GetRequest(string apiName, Dictionary<string, string> paramsDic)
+        {
+            return "";
+        }
+
+        /// <summary>
+        /// 开始POST请求
+        /// </summary>
+        /// <param name="apiName">具体请求的接口</param>
+        /// <param name="paramsDic">参数的字典</param>
+        /// <returns></returns>
+        private static string PostRequest(string apiName, Dictionary<string, string> paramsDic)
+        {
+            string result = "";
+            string content = BuildParams(paramsDic);
+            HttpWebResponse response;
+            //var url = $"{host}:{port}{apiName}{content}";
+            var url = $"{host }/{apiName}{content}";
+            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
+            request.Method = "POST";
+            SetHeader(request, apiName + content);
+            byte[] data = Encoding.UTF8.GetBytes(content.Substring(1));
+            request.ContentLength = data.Length;
+            using (Stream reqStream = request.GetRequestStream())
+            {
+                reqStream.Write(data, 0, data.Length);
+                reqStream.Close();
+            }
+            using (response = (HttpWebResponse)request.GetResponse())
+            {
+                if (response.StatusCode == HttpStatusCode.OK)
+                {
+                    var responseStream = response.GetResponseStream();
+                    using (StreamReader reader = new StreamReader(responseStream, encoding))
+                    {
+                        result = reader.ReadToEnd();
+                    }
+                }
+                else
+                {
+                    result = "接口请求失败,状态码:" + (int)response.StatusCode + response.StatusCode;
+                }
+            }
+            return result;
+        }
+    }
+}

+ 285 - 8
TEAMModelOS/Controllers/Third/XunFeiJYY/XunFeilJYYController.cs

@@ -21,6 +21,17 @@ using System.Net.Http.Json;
 using Azure.Core;
 using Microsoft.Azure.Cosmos;
 using System.Text.Json.Nodes;
+using TEAMModelOS.SDK.Context.Attributes.Azure;
+using Microsoft.Azure.Cosmos.Table;
+using System.Collections.Generic;
+using TEAMModelOS.SDK.Models;
+using Grpc.Core;
+using DocumentFormat.OpenXml.Spreadsheet;
+using System.ComponentModel.DataAnnotations;
+using DocumentFormat.OpenXml.InkML;
+using System.IdentityModel.Tokens.Jwt;
+using System.Linq;
+using System.Net.Http.Headers;
 
 
 namespace TEAMModelOS.Controllers.Third.XunFeiJYY
@@ -40,13 +51,26 @@ namespace TEAMModelOS.Controllers.Third.XunFeiJYY
         private static readonly string getUserInfo = "getUserInfo";
 
         private static readonly string url= "https://open.jyyun.com";
-        private static readonly string getUserByUserId = "getUserByUserId";
-
+       
+        
         private static readonly string appid = "ea4e44e1dea54caba7b06bdea72970fa";
         private static readonly string appsecret = "bb79a189fb9c22e9ae1a62b279a112c0";
         private static readonly string apikey = "305C300D06092A864886F70D0101010500034B003048024100C362EAB80DDFD682367592DD8274A40A9FE9F37DDEC56AC8E0FBE4A5A6D9F6FDAAA495460821CA94EF4A955B582822D7BB289142F2C562FC04DA2D3B940C3D730203010001";
         private static readonly string testuserid = "fbc284072a40da84adbe206f721b3285bc5101240c006447328c7afa3b7ae20d122a14a73144eea261756cce3e83c3f6ef940d9e8d823c7c";
         private static readonly string testschlid = "fbc284072a40da841b643aa367013eb18a1d351ed46b0feb15f629530e2f3c1137ae30823af5c69d3b88ef0fa3c761efee102032fc5d2a5a";
+        private static readonly string schoolid = "fbc284072a40da84352496274afc3bc55db54e6686cf3af22a9f0a295239691707dc038c5d090450c46bdea890254258b8a118406664bdaf";
+        //根据学校id查询学校下在读的学生 在读:行政班级表中grade不为104和105班级下的学生
+        private static readonly string listStudyingStudentInSchool = "listStudyingStudentInSchool";
+        //根据学校角色获取用户信息
+        private static readonly string listUserByRoleInScool = "listUserByRoleInScool";
+        //查询学校下行政班列表
+        private static readonly string listOrgClassBySchool = "listOrgClassBySchool";
+        //根据ID查询用户基本信息
+        private static readonly string getUserByUserId = "getUserByUserId";
+        //根据用户id获取教师信息
+        private static readonly string getOrgTeacherById = "getOrgTeacherById";
+        //根据学生id查询行政学生
+        private static readonly string getOrgStudentById = "getOrgStudentById";
         private readonly AzureCosmosFactory _azureCosmos;
         private readonly DingDing _dingDing;
         private readonly Option _option;
@@ -58,7 +82,7 @@ namespace TEAMModelOS.Controllers.Third.XunFeiJYY
         private readonly IHttpClientFactory _httpClientFactory;
 
         public XunFeilJYYController(ILogger<XunFeilJYYController> logger, IConfiguration configuration, IWebHostEnvironment environment, 
-            CoreAPIHttpService coreAPIHttpService, AzureStorageFactory azureStorage, DingDing dingDing, AzureCosmosFactory azureCosmos, IOptionsSnapshot<Option> option)  
+            CoreAPIHttpService coreAPIHttpService, AzureStorageFactory azureStorage, DingDing dingDing, AzureCosmosFactory azureCosmos, IOptionsSnapshot<Option> option, IHttpClientFactory httpClientFactory)  
         {
             _logger = logger;
             _configuration = configuration;
@@ -68,6 +92,14 @@ namespace TEAMModelOS.Controllers.Third.XunFeiJYY
             _dingDing = dingDing;
             _azureCosmos = azureCosmos;
             _option = option?.Value;
+            _httpClientFactory = httpClientFactory;
+        }
+        [HttpPost("update-student-data")]
+        [AllowAnonymous]
+        public async Task<IActionResult> UpdateStudentData(JsonElement json)
+        {
+            var  schoolData =    XunFeiService.Request( "Post", listOrgClassBySchool, new Dictionary<string, string>() { { "schoolId", testschlid } });
+            return Ok();
         }
         [HttpPost("gen-sso")]
         [AllowAnonymous]
@@ -89,14 +121,158 @@ namespace TEAMModelOS.Controllers.Third.XunFeiJYY
                 return Ok(new { code = 400, msg = "参数错误" });
             }
         }
+        [HttpPost("bind")]
+        [AllowAnonymous]
+        public async Task<IActionResult> Bind(XunFeiJYYBind bind)
+        {
+            string HostName = HttpContext.GetHostName();
+            if (!string.IsNullOrWhiteSpace(_option.HostName))
+            {
+                HostName = _option.HostName;
+            }
+            if (!_option.Location.Contains("Dep")  &&  !_option.Location.Contains("Test"))
+            {
+                HostName = "www.teammodel.cn";
+            }
+            var rurl = new StringBuilder($"https://{HostName}/lepei-sso");
+            try
+            {
+                TmdidImplicit tmdidImplicit = null;
+                int status = 0;
+                string msg = "账号未关联";
+                XunFeiJYYUser teacherLP = null;
+                var table = _azureStorage.GetCloudTableClient().GetTableReference("ScYxpt");
+                JsonNode encryptData = HttpUtility.UrlDecode(bind.param, Encoding.UTF8).ToObject<JsonNode>();
+                if (!string.IsNullOrWhiteSpace(bind.mobile))
+                {
+                    var coreUser = await _coreAPIHttpService.GetUserInfo(new Dictionary<string, string> { { "key", bind.mobile } }, _option.Location, _configuration);
+                    if (coreUser != null)
+                    {
+                        var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
+                        tmdidImplicit = await _coreAPIHttpService.Implicit(new Dictionary<string, string> {   { "grant_type", "implicit" },
+                                        { "client_id",clientID },
+                                        { "account",coreUser.id },
+                                        { "nonce",Guid.NewGuid().ToString()} }, _option.Location, _configuration);
+                        if (tmdidImplicit != null && !string.IsNullOrWhiteSpace(tmdidImplicit.id_token))
+                        {
+                            bind.id_token = tmdidImplicit.id_token;
+                        }
+                        else
+                        {
+                            status = 7;
+                        }
+                    }
+                    else
+                    {
+                        status = 7;
+
+                    }
+                }
+                if (string.IsNullOrWhiteSpace(bind.id_token))
+                {
+                    status =7;
+                }
+                else
+                {
+                    JwtSecurityToken jwt = new JwtSecurityToken(bind.id_token);
+                    var id = jwt.Payload.Sub;
+                    CoreUser coreUserById = await _coreAPIHttpService.GetUserInfo(new Dictionary<string, string> { { "key", $"{id}" } }, _option.Location, _configuration);
+                    if (coreUserById == null || string.IsNullOrWhiteSpace(coreUserById.mobile) || coreUserById.mobile.Length != 11)
+                    {
+                        status = 7;
+                    }
+                    jwt.Payload.TryGetValue("name", out object name);
+                    jwt.Payload.TryGetValue("picture", out object picture);
+
+                    List<XunFeiJYYUser> teachers = await table.FindListByDict<XunFeiJYYUser>(new Dictionary<string, object>() { { Constant.PartitionKey, $"XunFeiJYYUser" }, { Constant.RowKey, encryptData["user"]?["userId"] } });
+
+                    if (teachers.Any())
+                    {
+                        teacherLP=teachers.First();
+                        teacherLP.tmdid = id;
+                        teacherLP.mobile= coreUserById.mobile;
+                    }
+                    else {
+                        teacherLP= encryptData["user"].ToJsonString().ToObject<XunFeiJYYUser>();
+                        teacherLP.tmdid = id;
+                        teacherLP.mobile = coreUserById.mobile;
+                    }
+                    await table.SaveOrUpdate<XunFeiJYYUser>(teacherLP);
+                    status = 200;
+                }
+                if (status == 200)
+                {
+                    var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
+                    var location = _option.Location;
+                    var implicit_token = await _coreAPIHttpService.Implicit(
+                        new Dictionary<string, string>()
+                        {
+                                    { "grant_type", "implicit" },
+                                    { "client_id",clientID },
+                                    { "account",teacherLP.tmdid },
+                                    { "nonce",Guid.NewGuid().ToString()}
+                        }, location, _configuration);
+                    if (implicit_token != null&& !string.IsNullOrWhiteSpace(implicit_token.id_token))
+                    {
+                        rurl.Append($"?status={status}&msg={HttpUtility.UrlEncode("登录成功", Encoding.UTF8)}&id_token={implicit_token?.id_token}&access_token={implicit_token?.access_token}&expires_in={HttpUtility.UrlEncode(implicit_token?.expires_in)}&token_type={HttpUtility.UrlEncode(implicit_token?.token_type)}").ToString();
+                        return Ok(new {code=200, url = rurl.ToString() });
+                    }
+                    else
+                    {
+                        rurl.Append($"?status={status}&msg={HttpUtility.UrlEncode("隐式登录异常", Encoding.UTF8)}");
+                        return Ok(new { code = 400, url = rurl.ToString() });
+                    }
+
+                }
+                else if (status == 7)
+                {
+                    msg = $"教师账号:{encryptData["user"]?["userName"]}绑定失败";
+                    rurl.Append($"?status={status}&msg={HttpUtility.UrlEncode(msg, Encoding.UTF8)}&param={HttpUtility.UrlEncode(encryptData.ToJsonString(), Encoding.UTF8)}");
+                    return Ok(new { code = 400, url = rurl.ToString() });
+                }
+                else
+                {
+                    rurl.Append($"?status={7}&msg={HttpUtility.UrlEncode("账号未关联成功", Encoding.UTF8)}");
+                    return Ok(new { code = 400, url = rurl.ToString() });
+                }
+
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"讯飞绑定账号异常,{ex.Message},{ex.StackTrace},\n{bind.ToJsonString()}", GroupNames.成都开发測試群組);
+
+            }
+            rurl.Append($"?status={7}&msg={HttpUtility.UrlEncode("账号未关联成功", Encoding.UTF8)}");
+            return Ok(new { code = 400, url = rurl.ToString() });
+        }
+
+
+
         [HttpGet("sso")]
         [AllowAnonymous]
         public async Task<IActionResult> Sso([FromQuery]string accesstoken,[FromQuery]string state)
         {
+            string HostName = HttpContext.GetHostName();
+            int status = 0;
+            string msg = string.Empty;
+            var rurl = new StringBuilder($"https://{HostName}/xunfei-sso");
             //前端缓存accesstoken,用于做免登录验证。直接获取用户的Token .
             var  httpClient=  _httpClientFactory.CreateClient();
+            //HttpResponseMessage response_getOpenId  =  await httpClient.PostAsync($"{authurl}/{getOpenId}",new { appkey= appid , appsecret= appsecret, accessToken= accesstoken });
+            
+            //var request = new HttpRequestMessage();
+            //request.Method = new HttpMethod("POST");
+            //request.RequestUri = new Uri($"{authurl}/{getOpenId}");
+            //request.Content = new FormUrlEncodedContent(new Dictionary<string, string> { { "appkey", appid},{ "appsecret", appsecret },{ "accessToken" , "accesstoken" } });
+            //// 设置请求头中的Content-Type
+            ////  httpClient.DefaultRequestHeaders.Add("Content-Type", "application/x-www-form-urlencoded");
+            //var mediaTypeHeader = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
+            //mediaTypeHeader.CharSet = "UTF-8";
+            //request.Content.Headers.ContentType=mediaTypeHeader;
+            //  HttpResponseMessage response_getOpenId = await httpClient.SendAsync(request);
 
-            HttpResponseMessage response_getOpenId  =  await httpClient.PostAsJsonAsync($"{authurl}/{getOpenId}",new { appkey= appid , appsecret= appsecret, accessToken= accesstoken });
+            var response_getOpenId = await httpClient.PostAsync($"{authurl}/{getOpenId}", new StringContent($"appkey={appid}&appsecret={appsecret}&accessToken={accesstoken}", Encoding.UTF8, "application/x-www-form-urlencoded"));
+            XunFeiJYYUser user = null;
             if (response_getOpenId.IsSuccessStatusCode) 
             {
                 var result_getOpenId = await response_getOpenId.Content.ReadAsStringAsync();
@@ -108,20 +284,121 @@ namespace TEAMModelOS.Controllers.Third.XunFeiJYY
                 }
                 if (!string.IsNullOrEmpty(openId))
                 {
-                    HttpResponseMessage response_getUserInfo = await httpClient.PostAsJsonAsync($"{authurl}/{getUserInfo}", new { appkey = appid, openId = openId, accessToken = accesstoken });
+                    HttpResponseMessage response_getUserInfo = await httpClient.PostAsync($"{authurl}/{getUserInfo}", new StringContent($"appkey={appid}&openId={openId}&accessToken={accesstoken}", Encoding.UTF8, "application/x-www-form-urlencoded"));
                     if (response_getUserInfo.IsSuccessStatusCode) 
                     { 
                         var result_getUserInfo= await response_getUserInfo.Content.ReadAsStringAsync();
                         var result_getUserInfoData = result_getUserInfo.ToObject<JsonNode>();
                         JsonNode userIdNode = result_getUserInfoData["data"]?["userId"];
-                        if (!string.IsNullOrWhiteSpace($"{userIdNode}")) 
+                        if (!string.IsNullOrWhiteSpace($"{userIdNode}"))
                         {
-                        
+                            string result_getUserByUserId = await XunFeiJYYService.Request(httpClient, "Post", getUserByUserId, new Dictionary<string, string> { { "userId", $"{userIdNode.ToString()}" } });
+                            var result_getUserByUserIdData = result_getUserByUserId.ToObject<JsonNode>();
+                            var mobile = result_getUserByUserIdData["mobile"];
+                            if (string.IsNullOrWhiteSpace($"{mobile}"))
+                            {
+                                mobile=  result_getUserByUserIdData["phone"];
+                            }
+                            user = result_getUserInfoData["data"].ToJsonString().ToObject<XunFeiJYYUser>();
+                            user.RowKey= user.userId;
+                            user.PartitionKey="XunFeiJYYUser";
+                            var table = _azureStorage.GetCloudTableClient().GetTableReference("ScYxpt");
+                            StringBuilder tableSql = new($" PartitionKey eq 'OAuthShow'  and RowKey eq '{user.RowKey}'");
+                            //lambda 表达式排序
+                            List<XunFeiJYYUser> users = await table.QueryWhereString<XunFeiJYYUser>(tableSql.ToString());
+                            if (users.IsNotEmpty())
+                            {
+                                user.tmdid=users[0].tmdid;
+                            }
+                            await table.Update<XunFeiJYYUser>(user);
+                            string userKey = user.tmdid;
+                            if (string.IsNullOrWhiteSpace(userKey))
+                            {
+                                userKey=user.mobile;
+                            }
+
+                            if (!string.IsNullOrWhiteSpace(userKey))
+                            {
+                                var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
+                                var location = _option.Location;
+                                var implicit_token = await _coreAPIHttpService.Implicit(
+                                    new Dictionary<string, string>()
+                                    {
+                                    { "grant_type", "implicit" },
+                                    { "client_id",clientID },
+                                    { "account",userKey },
+                                    { "nonce",Guid.NewGuid().ToString()}
+                                    }, location, _configuration);
+                                if (implicit_token != null && !string.IsNullOrWhiteSpace(implicit_token.id_token))
+                                {
+                                    status = 200;
+                                    rurl.Append($"?status={status}&msg={HttpUtility.UrlEncode("登录成功", Encoding.UTF8)}&id_token={implicit_token?.id_token}&access_token={implicit_token?.access_token}&expires_in={HttpUtility.UrlEncode(implicit_token?.expires_in)}&token_type={HttpUtility.UrlEncode(implicit_token?.token_type)}").ToString();
+                                    return Ok(new { code = 200, url = rurl.ToString() });
+                                }
+                                else
+                                {
+                                    status=4;
+                                }
+                            }
+                            else
+                            {
+                                status=4;
+                            }
                         }
+                        else { 
+                            status=2;
+                            msg = "获取讯飞用户信息失败(userId)";
+                        }
+                    }
+                    else
+                    {
+                        status=2;
+                        msg = "获取讯飞用户信息失败(getUserInfo)";
                     }
                 }
+                else
+                {
+                    status=2;
+                    msg = "获取讯飞用户信息失败(openId)";
+                }
+            }
+            else
+            {
+                status=2;
+                msg = "获取讯飞用户信息失败(getOpenId)";
             }
-            return Ok(new { code = 200 });
+            if (status==4)
+            {
+                msg = $"科大讯飞教育云账号:{user?.userName}未关联";
+                rurl.Append($"?status={status}&msg={HttpUtility.UrlEncode(msg, Encoding.UTF8)}&param={HttpUtility.UrlEncode(new{ user , accesstoken = accesstoken,state}.ToJsonString(), Encoding.UTF8)}&type=xunfei-jjy&bindurl=xunfei-jjy/bind");
+            }
+            else {
+                rurl.Append($"?status={status}&msg={HttpUtility.UrlEncode(msg, Encoding.UTF8)}");
+            }
+            return Ok(new { code = 400, rurl= rurl.ToString() });
+        }
+        public class XunFeiJYYBind
+        {
+            [Required(ErrorMessage = "{0} 必须填写")]
+            public string param { get; set; }
+            public string id_token { get; set; }
+            public string mobile { get; set; }
+        }
+
+        [TableName(Name = "ScYxpt")]
+        public class XunFeiJYYUser : TableEntity
+        {
+            public string userId { get; set; }
+            public string userName { get; set; }
+            public string userPhoto { get; set; }
+            public string schoolId { get; set; }
+            public string schoolName { get; set; }
+            public string province { get; set; }
+            public string city { get; set; }
+            public string district { get; set; }
+            public string mobile { get; set; }
+            public string genderCode { get; set; }
+            public string  tmdid { get; set; }
         }
     }
 }