Browse Source

移植开放平台登录流程相关接口

Li 2 years ago
parent
commit
91378ecfd0

+ 0 - 43
TEAMModelBI/Tool/Extension/JwtAuth.cs

@@ -60,49 +60,6 @@ namespace TEAMModelBI.Models.Extension
             return serializeToken;
             return serializeToken;
         }
         }
 
 
-
-        /// <summary>
-        /// 第三方ID_token
-        /// </summary>
-        /// <param name="issuser"></param>
-        /// <param name="id"></param>
-        /// <param name="name"></param>
-        /// <param name="picture"></param>
-        /// <param name="webSite"></param>
-        /// <param name="salt"></param>
-        /// <param name="roles"></param>
-        /// <param name="permissions"></param>
-        /// <param name="expire"></param>
-        /// <returns></returns>
-        public static string CreateAuthTokenOpenBI(string issuser, string id, string name, string picture, string webSite, string salt, string[] roles = null, string[] permissions = null, int expire = 1) 
-        {
-
-            var payload = new JwtPayload
-            {
-                { JwtRegisteredClaimNames.Iss,issuser}, //发行者
-                { JwtRegisteredClaimNames.Sub,id},   //用户ID
-                { JwtRegisteredClaimNames.Exp,DateTimeOffset.UtcNow.AddHours(expire).ToUnixTimeSeconds().ToString()},//到期时间
-                { "name",name},//用户显示名称
-                { "picture",picture}, // 用户头像
-                { "roles",roles}, //登陆者的角色, (admin、dea) 
-                { "permissions",permissions}, //登陆者的权限
-                { JwtRegisteredClaimNames.Website,webSite}, // 平台站点
-            };
-            // 建立加密的秘钥
-            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt));
-            // HmacSha256 有要求必须要大于 128 bits,所以 salt 不能太短,至少要 16 字元以上
-            // https://stackoverflow.com/questions/47279947/idx10603-the-algorithm-hs256-requires-the-securitykey-keysize-to-be-greater
-            var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
-            var header = new JwtHeader(signingCredentials);
-            var secToken = new JwtSecurityToken(header, payload);
-            // 產出所需要的 JWT securityToken 物件,並取得序列化後的 Token 結果(字串格式)
-            var tokenHandler = new JwtSecurityTokenHandler();
-            //var securityToken = tokenHandler.CreateToken(tokenDescriptor);
-            var serializeToken = tokenHandler.WriteToken(secToken);
-            return serializeToken;
-
-        }
-
         /// <summary>
         /// <summary>
         /// 应用审核后生成的JwtKey秘钥
         /// 应用审核后生成的JwtKey秘钥
         /// </summary>
         /// </summary>

+ 42 - 0
TEAMModelOS.SDK/Extension/JwtAuthExtension.cs

@@ -188,6 +188,48 @@ namespace TEAMModelOS.SDK.Extension
                 return false;
                 return false;
             }
             }
         }
         }
+
+        /// <summary>
+        /// 第三方登录后的id_token
+        /// </summary>
+        /// <param name="issuser"></param>
+        /// <param name="id"></param>
+        /// <param name="name"></param>
+        /// <param name="picture"></param>
+        /// <param name="webSite"></param>
+        /// <param name="salt"></param>
+        /// <param name="roles"></param>
+        /// <param name="permissions"></param>
+        /// <param name="expire"></param>
+        /// <returns></returns>
+        public static string CreateBizLoginAuthToken(string issuser, string id, string name, string picture, string webSite, string salt, string[] roles = null, string[] permissions = null, int expire = 1)
+        {
+            var payload = new JwtPayload
+            {
+                { JwtRegisteredClaimNames.Iss,issuser}, //发行者
+                { JwtRegisteredClaimNames.Sub,id},   //用户ID
+                { JwtRegisteredClaimNames.Exp,DateTimeOffset.UtcNow.AddHours(expire).ToUnixTimeSeconds().ToString()},//到期时间
+                { "name",name},//用户显示名称
+                { "picture",picture}, // 用户头像
+                { "roles",roles}, //登陆者的角色, (admin、dea) 
+                { "permissions",permissions}, //登陆者的权限
+                { JwtRegisteredClaimNames.Website,webSite}, // 平台站点
+            };
+            // 建立加密的秘钥
+            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt));
+            // HmacSha256 有要求必须要大于 128 bits,所以 salt 不能太短,至少要 16 字元以上
+            // https://stackoverflow.com/questions/47279947/idx10603-the-algorithm-hs256-requires-the-securitykey-keysize-to-be-greater
+            var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
+            var header = new JwtHeader(signingCredentials);
+            var secToken = new JwtSecurityToken(header, payload);
+            // 產出所需要的 JWT securityToken 物件,並取得序列化後的 Token 結果(字串格式)
+            var tokenHandler = new JwtSecurityTokenHandler();
+            //var securityToken = tokenHandler.CreateToken(tokenDescriptor);
+            var serializeToken = tokenHandler.WriteToken(secToken);
+            return serializeToken;
+        }
+
+
     }
     }
     public enum OpenApiJtwIssuer
     public enum OpenApiJtwIssuer
     {
     {

+ 136 - 0
TEAMModelOS.SDK/Models/Cosmos/BI/BICommon/MonthStartEnd.cs

@@ -0,0 +1,136 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TEAMModelOS.SDK.Models
+{
+    public class MonthStartEnd
+    {
+        public string yearMonth { get; set; }
+
+        public long start { get; set; }
+
+        public long end { get; set; }
+
+    }
+
+    /// <summary>
+    /// 教师列表
+    /// </summary>
+    public class SchoolTeacherRoles
+    {
+        public string tmdId { get; set; }
+        public string tmdName { get; set; }
+    }
+
+    /// <summary>
+    /// 学校信息显示
+    /// </summary>
+    public record RecSchool
+    {
+        public string id { get; set; }
+        public string name { get; set; }
+        public string picture { get; set; }
+        public int type { get; set; }
+        public int size { get; set; }
+        public int scale { get; set; }
+    }
+
+    /// <summary>
+    /// 简单的基础信息Id、名称、图片
+    /// </summary>
+    public record BaseInfo
+    {
+        public string id { get; set; }
+        public string name { get; set; }
+        public string picture { get; set; }
+    }
+
+    /// <summary>
+    /// 用户和企业角色表
+    /// </summary>
+    public record RelBizInfo
+    {
+        public string userRowKey { get; set; }
+        public string relId { get; set; }
+        public string bizRowKey { get; set; }
+        public string bizName { get; set; }
+        public string bizCredit { get; set; }
+        public string bizPicture { get; set; }
+        public List<string> roles { get; set; }
+
+    }
+
+    /// <summary>
+    /// 课例、互动、活动的统计
+    /// </summary>
+    public record YearCnt
+    {
+        public string name { get; set; }
+        public int lessCnt { get; set; }
+        public int interCnt { get; set; }
+        public int actCnt { get; set; }
+    }
+
+    /// <summary>
+    /// 分析基础学校信息
+    /// </summary>
+    public record AnSchool
+    {
+        public string id { get; set; }
+        public string name { get; set; }
+        public string picture { get; set; }
+
+        /// <summary>
+        /// 1 普教,2 高职教
+        /// </summary>
+        public int type { get; set; }
+
+        public string areaId { get; set; }
+        public int size { get; set; }
+        /// <summary>
+        /// 学段
+        /// </summary>
+        public List<AnPeriod> period { get; set; }
+    }
+
+
+    /// <summary>
+    /// 学段
+    /// </summary>
+    public record AnPeriod
+    {
+        public string id { get; set; }
+        public string name { get; set; }
+        //public List<Major> majors { get; set; }
+        public List<string> grades { get; set; }
+        public List<Subject> subjects { get; set; }
+        public List<Semester> semesters { get; set; }
+    }
+
+    /// <summary>
+    /// 产品和版本的
+    /// </summary>
+    public record ScProdEd : RecSchool
+    {
+        public List<string> serial { get; set; } = new List<string>();
+
+        public List<string> service { get; set; } = new List<string>();
+        public List<string> hard { get; set; } = new List<string>();
+    }
+
+    /// <summary>
+    /// 课例分析
+    /// </summary>
+    public record LessAnalyse
+    {
+        public string id { get; set; }
+        public string code { get; set; }
+        public string periodId { get; set; }
+        public string subjectId { get; set; }
+        public List<string> grade { get; set; }
+    }
+
+}

+ 287 - 0
TEAMModelOS/Controllers/OpenApi/Business/BizUsersController.cs

@@ -0,0 +1,287 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.Models;
+using TEAMModelOS.SDK;
+using TEAMModelOS.SDK.Context.Constant;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK.Models;
+using TEAMModelOS.SDK.Models.Table;
+
+namespace TEAMModelOS.Controllers
+{
+    [Route("biz")]
+    [ApiController]
+    public class BizUsersController : ControllerBase
+    {
+        private readonly IConfiguration _configuration;
+        //数据容器
+        private readonly AzureCosmosFactory _azureCosmos;
+        //文件容器
+        private readonly AzureStorageFactory _azureStorage;
+        //钉钉提示信息
+        private readonly DingDing _dingDing;
+        private readonly Option _option;
+        //隐式登录
+        private readonly CoreAPIHttpService _coreAPIHttpService;
+        public BizUsersController(IConfiguration configuration, AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, DingDing dingDing, IOptionsSnapshot<Option> option, CoreAPIHttpService coreAPIHttpService)
+        {
+            _configuration = configuration;
+            _azureCosmos = azureCosmos;
+            _azureStorage = azureStorage;
+            _dingDing = dingDing;
+            _option = option?.Value;
+            _coreAPIHttpService = coreAPIHttpService;
+        }
+
+        /// <summary>
+        /// 开放平台用户登录
+        /// </summary>
+        /// <param name="jsonElement"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("get-bizuserlogin")]
+        public async Task<IActionResult> GetCommpanyLogin(JsonElement jsonElement) 
+        {
+            jsonElement.TryGetProperty("mobile", out JsonElement mobile);
+            jsonElement.TryGetProperty("tmdId", out JsonElement tmdId);
+            jsonElement.TryGetProperty("mail", out JsonElement mail);
+            if (!jsonElement.TryGetProperty("pwd", out JsonElement password)) return BadRequest();
+
+            var tableClient = _azureStorage.GetCloudTableClient();
+            var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
+            Dictionary<string, object> tableDic = new();
+            string tableSql = null;
+            if (!string.IsNullOrEmpty($"{mail}"))
+            {
+                tableSql = $" PartitionKey eq 'BusinessUser' and mail eq '{mail}'";
+                //tableDic = new Dictionary<string, object>() { { "PartitionKey", "BizRelUser" }, { "mail", $"{mail}" } };
+            }
+            if (!string.IsNullOrEmpty($"{tmdId}"))
+            {
+                tableSql = $" PartitionKey eq 'BusinessUser' and tmdId eq '{tmdId}'";
+                //tableDic = new Dictionary<string, object>() { { "PartitionKey", "BizRelUser" }, { "tmdId", $"{tmdId}" } };
+            }
+            if (!string.IsNullOrEmpty($"{mobile}"))
+            {
+                tableSql = $" PartitionKey eq 'BusinessUser' and mobile eq '{mobile}'";
+                //tableDic = new Dictionary<string, object>() { { "PartitionKey", "BizRelUser" }, { "mobile", $"{mobile}" } };
+            }
+
+            if (!string.IsNullOrEmpty(tableSql))
+            {
+                var table = tableClient.GetTableReference("IESOpenApi");
+                List<BusinessUser> findBizUsers = await table.QueryWhereString<BusinessUser>(tableSql);
+                //List<BusinessUser> findBizUsers = await table.FindListByDict<BusinessUser>(tableDic);
+                if (findBizUsers.Count > 0)
+                {
+                    BusinessUser bizUser = new();
+                    foreach (var item in findBizUsers)
+                    {
+                        bizUser.PartitionKey = item.PartitionKey;
+                        bizUser.RowKey = item.RowKey;
+                        bizUser.name = item.name;
+                        bizUser.picture = item.picture;
+                        bizUser.tmdId = item.tmdId;
+                        bizUser.mobile = item.mobile;
+                        bizUser.mail = item.mail;
+                        bizUser.salt = item.salt;
+                        bizUser.pwd = item.pwd;
+                    }
+                    List<BizRelUser> bizRelUsers = new();
+
+                    List<RelBizInfo> relBizInfos = new();
+                    if (bizUser != null)
+                    {
+                        string tableSqlUser = $"PartitionKey eq 'BizRelUser' and userId eq '{bizUser.RowKey}'";
+                        bizRelUsers = await table.QueryWhereString<BizRelUser>(tableSqlUser);
+                        if (bizRelUsers.Count > 0)
+                        {
+                            foreach (var item in bizRelUsers)
+                            {
+                                BusinessConfig businessConfig = table.Get<BusinessConfig>("BusinessConfig", item.bizId);
+                                RelBizInfo relBizInfo = new()
+                                {
+                                    userRowKey = item.userId,
+                                    relId = item.RowKey,
+                                    bizRowKey = item.bizId,
+                                    roles = !string.IsNullOrEmpty($"{item.roles}") ? new List<string>(item.roles.Split(',')) : new List<string>()
+                                };
+                                if (businessConfig != null)
+                                {
+                                    relBizInfo.bizName = businessConfig.name;
+                                    relBizInfo.bizCredit = businessConfig.credit;
+                                    relBizInfo.bizPicture = businessConfig.picture;
+                                    relBizInfos.Add(relBizInfo);
+                                }
+                            }
+                        }
+                    }
+                    var hashedPw = Utils.HashedPassword(password.ToString(), bizUser.salt.ToString());
+                    if (hashedPw.Equals(bizUser.pwd))
+                    {
+                        string openid_token = JwtAuthExtension.CreateBizLoginAuthToken(_option.HostName, bizUser.RowKey?.ToString(), bizUser.name?.ToString(), bizUser.picture?.ToString(), $"{_option.Location}-Open", _option.JwtSecretKey, expire: 3);
+
+                        await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", $"{bizUser.name}【{bizUser.RowKey}】登录商务智能开放平台", _dingDing, tid: bizUser.RowKey, tname: bizUser.name, twebsite: _option.Location, httpContext: HttpContext);
+                        return Ok(new { state = RespondCode.Ok, openid_token, bizUser, relBizInfos });
+                    }
+                    else return Ok(new { state = RespondCode.ForbiddenPwd, msg = "密码错误!" });
+                }
+                else return Ok(new { state = RespondCode.NotFound, msg = "该账户不存在" });
+            }
+            else return Ok(new { state = RespondCode.ParamsError, msg = "参数错误" });
+        }
+
+
+        /// <summary>
+        /// 注册开放平台用户
+        /// </summary>
+        /// <param name="jsonElement"></param>
+        /// <returns></returns>
+        [HttpPost("set-ropen")]
+        public async Task<IActionResult> SetRegistered(JsonElement jsonElement)
+        {
+            if (!jsonElement.TryGetProperty("name", out JsonElement name)) return BadRequest();
+            if (!jsonElement.TryGetProperty("mobile", out JsonElement mobile)) return BadRequest();
+            jsonElement.TryGetProperty("tmdId", out JsonElement tmdId);
+            jsonElement.TryGetProperty("mail", out JsonElement mail);
+            jsonElement.TryGetProperty("pwd", out JsonElement pwd);
+
+            string Website = "China";
+            var tableClient = _azureStorage.GetCloudTableClient();
+            var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
+
+            var table = tableClient.GetTableReference("IESOpenApi");
+
+            string salt = Utils.CreatSaltString(8);
+
+            BusinessUser bizUser = null;
+            List<BusinessUser> findBizUsers = await table.QueryWhereString<BusinessUser>($" PartitionKey eq 'BusinessUser' and mobile eq '{mobile}'");
+            if (findBizUsers.Count <= 0)
+            {
+                var coreUser = await _coreAPIHttpService.GetUserInfo(new Dictionary<string, string> { { "key", $"{mobile}" } }, _option.Location, _configuration);
+
+                if (coreUser != null)
+                    bizUser = new() { RowKey = Guid.NewGuid().ToString(), name = coreUser.name, tmdId = coreUser.id, mobile = coreUser.mobile, mail = coreUser.mail, salt = salt, pwd = string.IsNullOrEmpty($"{pwd}") ? Utils.HashedPassword($"{mobile}", salt) : Utils.HashedPassword($"{pwd}", salt) };
+                else
+                    bizUser = new() { RowKey = Guid.NewGuid().ToString(), name = $"{name}", mobile = $"{mobile}", salt = salt, pwd = string.IsNullOrEmpty($"{pwd}") ? Utils.HashedPassword($"{mobile}", salt) : Utils.HashedPassword($"{pwd}", salt) };
+
+                bizUser = await table.Save<BusinessUser>(bizUser);
+
+                await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "bizUser-update", $"{bizUser.name}【{bizUser.RowKey}】注册开放平台用户", _dingDing, tid: bizUser.RowKey, tname: bizUser.name, twebsite: Website?.ToString(), httpContext: HttpContext);
+                return Ok(new { state = RespondCode.Ok, bizUser });
+            }
+            else return Ok(new { state = RespondCode.Conflict, msg = "该手机号已注册开放平台,请直接登录" });
+        }
+
+        /// <summary>
+        /// 查询企业详细信息
+        /// </summary>
+        /// <param name="jsonElenent"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("get-info")]
+        public async Task<IActionResult> GetInfo(JsonElement jsonElenent)
+        {
+            try
+            {
+                if(!jsonElenent.TryGetProperty("id", out JsonElement id)) return BadRequest();
+                var cosmosClient = _azureCosmos.GetCosmosClient();
+                var tableClient = _azureStorage.GetCloudTableClient();
+
+                var table = tableClient.GetTableReference("IESOpenApi");
+                Dictionary<string, object> keyValue = new() { { "PartitionKey", "BusinessConfig" } };
+                if (!string.IsNullOrEmpty($"{id}"))
+                {
+                    keyValue.Add("RowKey", $"{id}");
+                }
+
+                List<BusinessConfig> companys = table.FindListByDictSync<BusinessConfig>(keyValue);
+
+                return Ok(new { state = RespondCode.Ok, companys });
+            }
+            catch (Exception e)
+            {
+                await _dingDing.SendBotMsg($"BI,{_option.Location} , /biz/get-info   \n {e.Message}\n{e.StackTrace} \n ", GroupNames.成都开发測試群組);
+                return BadRequest();
+            }
+        }
+
+        /// <summary>
+        /// 重新秘钥token
+        /// </summary>
+        /// <param name="jsonElement"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("reset-bus")]
+        public async Task<IActionResult> ResetBus(JsonElement jsonElement)
+        {
+            try
+            {
+                if (!jsonElement.TryGetProperty("id", out JsonElement id)) return BadRequest();
+                var table = _azureStorage.GetCloudTableClient().GetTableReference("IESOpenApi");
+
+                List<BusinessConfig> busConfigs = await table.FindListByDict<BusinessConfig>(new Dictionary<string, object>() { { "PartitionKey", "BusinessConfig" }, { "RowKey", $"{id}" } });
+                if (busConfigs.Count > 0)
+                {
+                    foreach (var busConfig in busConfigs)
+                    {
+                        var auth_token = JwtAuthExtension.CreateBusinessApiToken(_option.Location, busConfig.RowKey, _option.JwtSecretKey, "business");
+                        busConfig.jti = auth_token.jti;
+                        busConfig.token = auth_token.jwt;
+                    }
+                    await table.SaveOrUpdateAll(busConfigs);
+                    return Ok(new { state = RespondCode.Ok, busConfigs });
+                }
+                else
+                    return Ok(new { state = RespondCode.ParamsError, msg = "未找到企业信息" });
+            }
+            catch (Exception e)
+            {
+                await _dingDing.SendBotMsg($"BI,{_option.Location} , /biz/reset-bus  \n {e.Message}\n{e.StackTrace} \n ", GroupNames.成都开发測試群組);
+                return BadRequest();
+            }
+        }
+
+
+        /// <summary>
+        /// 依据企业ID查询关联的学校
+        /// </summary>
+        /// <param name="jsonElement"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("get-companyschool")]
+        public async Task<IActionResult> GetCompanySc(JsonElement jsonElement)
+        {
+            try
+            {
+                if(!jsonElement.TryGetProperty("id", out JsonElement id)) return BadRequest();
+
+                var table = _azureStorage.GetCloudTableClient().GetTableReference("IESOpenApi");
+                Dictionary<string, object> keyValue = new() { { "PartitionKey", $"BusinessSchool" } };
+
+                if (!string.IsNullOrEmpty($"{id}"))
+                {
+                    keyValue.Add("bizid", $"{id}");
+                }
+
+                List<BusinessSchool> busSchools = await table.FindListByDict<BusinessSchool>(keyValue);
+
+                return Ok(new { state = 200, busSchools });
+            }
+            catch (Exception e)
+            {
+                await _dingDing.SendBotMsg($"BI,{_option.Location} , /biz/get-companyschool   \n {e.Message}\n{e.StackTrace} \n ", GroupNames.成都开发測試群組);
+                return BadRequest();
+            }
+        }
+
+
+    }
+}