CrazyIter_Bin 3 年之前
父節點
當前提交
1d84b326a7

+ 2 - 2
TEAMModelOS.FunctionV4/ServiceBus/ActiveTaskTopic.cs

@@ -969,7 +969,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                                     LessonBase lessonBase = baseblobDownload.Content.ToObjectFromJson<LessonBase>();
                                     if (lessonBase != null  && lessonBase.summary!=null)
                                     {
-                                        lessonRecord.name = lessonBase.summary.activityName;
+                                        //lessonRecord.name = lessonBase.summary.activityName;
                                         lessonRecord.attendCount = lessonBase.summary.attendCount;
                                         lessonRecord.clientCount = lessonBase.summary.clientCount;
                                         lessonRecord.attendRate = lessonBase.summary.attendRate;
@@ -1227,7 +1227,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                                             int limit = teacher.lessonLimit;
                                             if (teacher.lessonLimit == 0)
                                             {
-                                                //未设置的的采用系统设置的默认值30
+                                                //未设置的的采用系统设置的默认值50
                                                 limit = Constant.private_lesson_limit;
                                             }
                                             if (ids.Count >= limit)

+ 1 - 1
TEAMModelOS.SDK/Models/Cosmos/Teacher/Research/TeacherTrain.cs

@@ -58,7 +58,7 @@ namespace TEAMModelOS.SDK.Models
         /// <summary>
         /// 包含选修的
         /// </summary>
-        public Currency currencyAll { get; set; }= new Currency();
+        //  public Currency currencyAll { get; set; }= new Currency();
         public List<OfflineRecord> offlineRecords { get; set; } = new List<OfflineRecord>();
         /// <summary>
         /// 教师课堂实录

+ 4 - 0
TEAMModelOS.SDK/Models/Service/Third/Xkw/XkwOAuthModel.cs

@@ -45,6 +45,8 @@ namespace TEAMModelOS.SDK.Models
         /// 单点认证平台名称
         /// </summary>
         public string Name { get; set; }
+        //自定义域名情况
+        public string Domain { get; set; }
     }
 
     [TableName(Name = "IESOAuth")]
@@ -56,6 +58,7 @@ namespace TEAMModelOS.SDK.Models
         public string Name { get; set; }
         public long Time { get; set; }
         public string Type { get; set; }
+        public string Domain { get; set; }
     }
     public class XkwBindModel
     {
@@ -64,6 +67,7 @@ namespace TEAMModelOS.SDK.Models
         public string accessToken { get; set; }
         public string openId { get; set; }
         public string userId { get; set; }
+        public string domain { get; set; }
     }
     public record OAuthCode {
         public string code { get; set; }

+ 1 - 1
TEAMModelOS.SDK/Models/Table/OptLog.cs

@@ -6,7 +6,7 @@ using Microsoft.Azure.Cosmos.Table;
 
 namespace TEAMModelOS.SDK.Models.Table
 {    
-    [TableName(Name = "OptLog")]
+    [TableName(Name = "IESOptLog")]
     public class OptLog : TableEntity
     {
         /// <summary>

+ 1 - 1
TEAMModelOS/ClientApp/src/view/evaluation/bank/index.vue

@@ -213,7 +213,7 @@ export default {
       return this.$store.state.totalAnalysis.paperScrollTop
     },
 	isTestSite(){
-		return window.location.host === 'test.teammodel.cn'
+		return window.location.host === 'kong.sso.com:5000'
 	}
   },
   // beforeRouteEnter(to, from, next) {

+ 9 - 0
TEAMModelOS/ClientApp/src/view/xkw/xkw.vue

@@ -6,6 +6,15 @@ export default {
         this.$api.auth.xkwAuthorize({
           module: localStorage.getItem('xkw_module', module),
           code: this.$route.query.code
+        }).then(res => {
+            if (res.status == 0) {
+                this.$Modal.info({
+                    title: "°ó¶¨ÐÅÏ¢",
+                    content: res.msg
+                })
+            } else {
+                window.location.replace(res.url)
+            }
         })
     },
 }

+ 2 - 1
TEAMModelOS/Controllers/Third/OAuth2Controller.cs

@@ -98,9 +98,10 @@ namespace TEAMModelOS.Controllers.Third
         [AuthToken(Roles = "teacher,admin,area,student")]
         public async Task<IActionResult> Bind(JsonElement json)
         {
+            string domain = HttpContext?.Request?.Host.Host;
             var (tmdid, _, _, school) = HttpContext.GetAuthTokenInfo();
             var table = _azureStorage.GetCloudTableClient().GetTableReference("IESOAuth");
-            List<OAuthUser> authUsers = await table.FindListByDict<OAuthUser>(new Dictionary<string, object>() { { "RowKey", tmdid } });
+            List<OAuthUser> authUsers = await table.FindListByDict<OAuthUser>(new Dictionary<string, object>() { { "RowKey", tmdid },{ "Domain" ,domain} });
             return Ok(new { auth = authUsers.Select(x => new { type = x.Type, tmdid = x.RowKey, time = x.Time }) });
         }
     }

+ 1 - 0
TEAMModelOS/Controllers/Third/Sc/ScController.cs

@@ -473,6 +473,7 @@ namespace TEAMModelOS.Controllers
         public async Task<IActionResult> Sso([FromQuery] ScSSO scsso, string path)
         {
             string HostName = HttpContext.GetHostName();
+
             if (!string.IsNullOrWhiteSpace(_option.HostName)) {
                 HostName = _option.HostName;
             }

+ 3 - 2
TEAMModelOS/Controllers/Third/Xkw/OpenAuthClient.cs

@@ -43,6 +43,7 @@ namespace TEAMModelOS.Controllers.Third.Xkw
 
     public class XkwOAuthClient : OpenAuthClient
     {
+        public string Domain { get; set; }
         public string AUTH_HOST { get; set; }
         public string AUTH_URL { get; set; }
         public string TOKEN_URL { get; set; }
@@ -56,7 +57,7 @@ namespace TEAMModelOS.Controllers.Third.Xkw
         /// </summary>
         public string Extra { get; set; }
         public string ErrorMessage { get; set; }
-        public XkwOAuthClient(string appKey, string appSecret, string redirectUrl, string oauthHost, string accessToken = null, string openid = null, string userId = null)
+        public XkwOAuthClient(string appKey, string appSecret, string redirectUrl, string oauthHost,string domain, string accessToken = null, string openid = null, string userId = null)
             : base(appKey, appSecret, redirectUrl, accessToken)
         {
             ClientName = "Xkw Demo Client";
@@ -66,7 +67,7 @@ namespace TEAMModelOS.Controllers.Third.Xkw
             AUTH_URL = AUTH_HOST + "authorize";
             TOKEN_URL = AUTH_HOST + "accessToken";
             PROFILE_URL = AUTH_HOST + "profile";
-
+            Domain = domain;
             if (!(string.IsNullOrEmpty(accessToken) && string.IsNullOrEmpty(openid)))
             {
                 isAccessTokenSet = true;

+ 42 - 23
TEAMModelOS/Controllers/Third/Xkw/XkwOAuth2Controller.cs

@@ -103,16 +103,18 @@ namespace TEAMModelOS.Controllers
         [Authorize(Roles = "IES")]
         [AuthToken(Roles = "teacher,admin,area,student")]
         public async Task<IActionResult> Aauth(OAuthCode authCode) {
+            string domain =  HttpContext?.Request?.Host.Host;
+            var req = HttpContext?.Request;
             //https://ssoserviceurl/oauth2/authorize?client_id=APPKEY&openid=OPENID=&service=SERVICE
             var (tmdid, _, _, school) = HttpContext.GetAuthTokenInfo();
 
             StringValues accessToken = "";//应该从别的地方获取 不是mvc 无法从Session 获取 
-            HttpContext.Request.Headers.TryGetValue($"XKW-AccessToken", out accessToken);
+            HttpContext.Request.Headers.TryGetValue($"xkw-AccessToken", out accessToken);
             if (!_option.Location.Contains("China"))
             {
                 return BadRequest();
             }
-            var client = await GetOpenAuthClient(tmdid, accessToken);
+            var client = await GetOpenAuthClient(tmdid, accessToken, domain);
             if (authCode.agree == 1) {
                 //获取醍摩豆id的手机号
                 var keys =new List<string> { tmdid};
@@ -138,7 +140,7 @@ namespace TEAMModelOS.Controllers
         {
             var (tmdid, _, _, school) = HttpContext.GetAuthTokenInfo();
             StringValues accessToken ;//应该从别的地方获取 不是mvc 无法从Session 获取 
-            HttpContext.Request.Headers.TryGetValue($"XKW-AccessToken", out accessToken);
+            HttpContext.Request.Headers.TryGetValue($"xkw-AccessToken", out accessToken);
             if (!_option.Location.Contains("China"))
             {
                 return BadRequest();
@@ -148,31 +150,49 @@ namespace TEAMModelOS.Controllers
             {
                 return RedirectToAction("Index");
             }
-            var client =await GetOpenAuthClient(tmdid, accessToken);
-            string schoolId = "tmdedu";
-            if (_option.Location.Contains("Test", StringComparison.OrdinalIgnoreCase) || _option.Location.Contains("Dep", StringComparison.OrdinalIgnoreCase))
-            {
-                schoolId = "3082";
-            }
+            string domain = HttpContext?.Request?.Host.Host;
+            var client =await GetOpenAuthClient(tmdid, accessToken, domain);
+            string schoolId = "teammodel.cn";
+            //学科网测试
+            //if (schoolId.Equals("kong.sso.com"))
+            //{
+            //    schoolId = "3082";
+            //}
             client.GetAccessTokenByCode(authCode.code, schoolId);
             //未登录已认证学科网用户
             if (string.IsNullOrEmpty(client.UserId) || "".Equals(client.UserId.Trim()))
             {
-                return Redirect($"bind?status=0&accessToken={client.AccessToken}&openId={client.OpenId}&userId={client.UserId}&msg={HttpUtility.UrlEncode("未登录")}");
+
+                return Ok(new { status = 0, msg = "未登录" });
+               // return Redirect($"bind?status=0&accessToken={client.AccessToken}&openId={client.OpenId}&userId={client.UserId}&domain={domain}&msg={HttpUtility.UrlEncode("未登录")}");
             }
             if (string.IsNullOrEmpty(client.OpenId))
             {
                 string errorMsg = "学科网"+client.ErrorMessage;
-                return Redirect($"bind?status=0&accessToken={client.AccessToken}&openId={client.OpenId}&userId={client.UserId}&msg={HttpUtility.UrlEncode(errorMsg)}");
+                return Ok(new { status = 0, msg = errorMsg });
+               // return Redirect($"bind?status=0&accessToken={client.AccessToken}&openId={client.OpenId}&userId={client.UserId}&domain={domain}&msg={HttpUtility.UrlEncode(errorMsg)}");
             }
 
             if (client.IsAuthorized || !string.IsNullOrWhiteSpace(client.OpenId))
             {
-                return Redirect($"bind?status=1&accessToken={client.AccessToken}&openId={client.OpenId}&userId={client.UserId}&msg={HttpUtility.UrlEncode("认证成功")}");
+                var table = _azureStorage.GetCloudTableClient().GetTableReference("IESOAuth");
+                OAuthUser authUser = new OAuthUser
+                {
+                    PartitionKey = $"OAuthUser-xkw-{domain}",
+                    RowKey = client.UserId,
+                    OpenId = client.OpenId,
+                    Domain = domain,
+                    Time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                    Type = "xkw"
+                };
+                await table.SaveOrUpdate<OAuthUser>(authUser);
+                return Ok(new { status = 1, url=client.SERVICE_URL});
+                //return Redirect($"bind?status=1&accessToken={client.AccessToken}&openId={client.OpenId}&userId={client.UserId}&domain={domain}&msg={HttpUtility.UrlEncode("认证成功")}");
             }
             else
             {
-                return Redirect($"bind?status=0&accessToken={client.AccessToken}&openId={client.OpenId}&userId={client.UserId}&msg={HttpUtility.UrlEncode("认证失败")}");
+                return Ok(new { status = 0, msg = "认证失败" });
+                //  return Redirect($"bind?status=0&accessToken={client.AccessToken}&openId={client.OpenId}&userId={client.UserId}&domain={domain}&msg={HttpUtility.UrlEncode("认证失败")}");
             }
         }
         
@@ -185,11 +205,12 @@ namespace TEAMModelOS.Controllers
                 var table = _azureStorage.GetCloudTableClient().GetTableReference("IESOAuth");
                 OAuthUser authUser = new OAuthUser
                 {
-                    PartitionKey = "OAuthUser-Xkw",
+                    PartitionKey = $"OAuthUser-xkw-{authCode.domain}",
                     RowKey = authCode.userId,
                     OpenId = authCode.openId,
+                    Domain = authCode.domain,
                     Time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
-                    Type = "Xkw"
+                    Type = "xkw"
                 };
                 await table.SaveOrUpdate<OAuthUser>(authUser);
                 return Ok(new { status=authCode.status, msg = "绑定成功!" });
@@ -197,8 +218,8 @@ namespace TEAMModelOS.Controllers
             else {
                 return Ok(new { status = authCode.status, msg = authCode.msg });
             }
-           
         }
+      
         [HttpGet("unbind")]
         public async Task<IActionResult> Unbind(String openId, String userId)
         {
@@ -237,7 +258,7 @@ namespace TEAMModelOS.Controllers
         /// 封装一个方法来初始化OpenAuth客户端
         /// </summary>
         /// <returns></returns>
-        private async Task<XkwOAuthClient> GetOpenAuthClient(string tmdid,string accessToken)
+        private async Task<XkwOAuthClient> GetOpenAuthClient(string tmdid,string accessToken,string domain)
         {
             var table = _azureStorage.GetCloudTableClient().GetTableReference("IESOAuth");
             //var accessToken = Session["access_token"] == null ? string.Empty : (string)Session["access_token"];
@@ -248,14 +269,11 @@ namespace TEAMModelOS.Controllers
                                 // var settings = ConfigurationManager.AppSettings;
                                 // var client = new XkwOAuthClient(settings["OAuth_Xkw_AppKey"], settings["OAuth_Xkw_AppSecret"], settings["OAuth_Xkw_RedirectUrl"], settings["OAuth_Xkw_OAuthHost"], accessToken, openId, userId);
 
-            List<OAuthUser> authUsers = await table.FindListByDict<OAuthUser>(new Dictionary<string, object>() { { "PartitionKey", "OAuthUser-Xkw" }, { "RowKey", tmdid } });
+            List<OAuthUser> authUsers = await table.FindListByDict<OAuthUser>(new Dictionary<string, object>() { { "PartitionKey", "OAuthUser-xkw" }, { "RowKey", tmdid } });
             if (authUsers.Any()) {
                 openId = authUsers[0].OpenId;
             }
-            string RowKey = "Xkw";
-            if (_option.Location.Contains("Test", StringComparison.OrdinalIgnoreCase) || _option.Location.Contains("Dep", StringComparison.OrdinalIgnoreCase)) {
-                RowKey = "Xkw-Test";
-            }
+            string RowKey = $"xkw-{domain}";
             List<OAuthComConfig> configs = await table.FindListByDict<OAuthComConfig>(new Dictionary<string, object>() { { "PartitionKey", "OAuthComConfig" }, { "RowKey", RowKey } });
             if (configs.Any())
             {
@@ -264,7 +282,8 @@ namespace TEAMModelOS.Controllers
                 string OAuth_Xkw_RedirectUrl = configs[0].RedirectUrl;
                 string OAuth_Xkw_OAuthHost = configs[0].OAuthHost;
                 string OAuth_Xkw_ServiceUrl = configs[0].ServiceUrl;
-                var client = new XkwOAuthClient(OAuth_Xkw_AppKey, OAuth_Xkw_AppSecret, OAuth_Xkw_RedirectUrl, OAuth_Xkw_OAuthHost, accessToken, openId, userId);
+                string OAuth_Xkw_Domain= configs[0].Domain;
+                var client = new XkwOAuthClient(OAuth_Xkw_AppKey, OAuth_Xkw_AppSecret, OAuth_Xkw_RedirectUrl, OAuth_Xkw_OAuthHost, OAuth_Xkw_Domain, accessToken, openId, userId);
                 client.SERVICE_URL = OAuth_Xkw_ServiceUrl;
                 return client;
             }

+ 88 - 88
TEAMModelOS/Controllers/XTest/TestController.cs

@@ -760,15 +760,18 @@ namespace TEAMModelOS.Controllers
         }
         [HttpPost("get-teacher-ability-files")]
         public async Task<IActionResult> GetScteacher(JsonElement json) {
-
+            if (!json.TryGetProperty("areaId", out JsonElement _areaId)) { return BadRequest(); }
+            Area area= await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemAsync<Area>($"{_areaId}", new PartitionKey("Base-Area"));
             List<string> teachers = new List<string>();
+            //获取这个区的教师
             string schoolSql = "SELECT value  c.id FROM c join a in c.schools where a.areaId='870a5a6b-1ab3-461a-bdeb-baec19780ddb' and c.code='Base' ";
             await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher)
                 .GetItemQueryIterator<string>(schoolSql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base") }))
             {
                 teachers.Add(item);
             }
-            string tr =$"SELECT value(c) FROM c  where c.id in ({string.Join(",", teachers.Select(x=>$"'{x}'"))}) and  c.pk='TeacherTrain' ";
+            //获取这些老师的研修记录
+            string tr =$"SELECT distinct value(c) FROM c join a in c.currency.teacherAilities  where c.id in ({string.Join(",", teachers.Select(x=>$"'{x}'"))}) and  c.pk='TeacherTrain' and a.videoTime<300  ";
             List<TeacherTrain> teacherTrains = new List<TeacherTrain>();
             await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher)
                 .GetItemQueryIterator<TeacherTrain>(tr, requestOptions: new QueryRequestOptions {  }))
@@ -777,118 +780,112 @@ namespace TEAMModelOS.Controllers
                     teacherTrains.Add(item);
                 }
             }
-            string sql = $" select distinct  value(b.id ) from c join b in c.children  where  c.code='AbilityTask-standard10'  ";
+            //获取这个区的能力点树状结构
+            string sql = $" select distinct  value(b.id ) from c join b in c.children  where  c.code='AbilityTask-{area.standard}'  ";
             List<string> nodeIdsDB = new List<string>();
             await foreach (var y in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).GetItemQueryIterator<string>
-                  (sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"AbilityTask-standard10") }))
+                  (sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"AbilityTask-{area.standard}") }))
             {
                 nodeIdsDB.Add(y);
             }
-            List<string> right=new List<string>();
-            List<string> left=new List<string>();
             foreach (var item in teacherTrains)
             {
-                if (item.onlineTime > 2)
+                List<TeacherAbility> teacherAbility = new List<TeacherAbility>();
+                if (item.currency.teacherAilities.Count() > 3)
+                {
+                    //如果选择了大于三个能力点的教师,则优先获取上传了认证材料的的能力点,
+                    var uploadHas=  item.currency.teacherAilities.FindAll(x => x.uploadHas == 1);
+                    if (uploadHas.Any()) {
+                        teacherAbility.AddRange(uploadHas);
+                    }
+                    // 如果仍然未满足数量。则再去获取 没有上传认证材料,但是又有学习时间长的能力点。
+                    var hasVideoTime = item.currency.teacherAilities.FindAll(x => x.uploadHas != 1);
+                }
+                else {
+                    teacherAbility.AddRange(item.currency.teacherAilities);
+                }
+
+                TeacherFile teacherFile = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<TeacherFile>(item.id, new PartitionKey($"TeacherFile-{item.code.Replace("TeacherTrain-", "")}"));
+                foreach (var x in item.currency.teacherAilities)
                 {
-                    TeacherFile teacherFile = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<TeacherFile>(item.id, new PartitionKey($"TeacherFile-{item.code.Replace("TeacherTrain-", "")}"));
-                    var nodeIds=  teacherFile.fileRecords.SelectMany(x => x.files).Select(x => x.nodeId).ToHashSet();
-                    bool expect = false;
-                    if (nodeIds.Any()) 
+                    //某个能力点大于300
+                    if (x.videoTime >= 300) {
+                        continue;
+                    }
+                    string sqls = $" select value(c) from c  where c.abilityId='{x.id}' and c.code='AbilityTask-{area.standard}'";
+                    List<AbilityTask> abilityTasks = new List<AbilityTask>();
+                    Dictionary<string, RecordFileAbility> valuePairs = new Dictionary<string, RecordFileAbility>();
+                    await foreach (var y in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).GetItemQueryIterator<AbilityTask>
+                            (sqls, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"AbilityTask-{area.standard}") }))
                     {
-                        var exp=  nodeIds.Except(nodeIdsDB);
-                        if (exp.Any()) 
-                        {
-                            expect = true;
-                            List<FileAbility> dels = new List<FileAbility>();
-                            teacherFile.fileRecords.ForEach(x => {
-                                x.files.RemoveAll(z => exp.Contains(z.nodeId));
-                            });
-                        }
+                        abilityTasks.Add(y);
                     }
-                    if (expect)
+                    //   double limit = 0;
+                    abilityTasks.ForEach(x =>
                     {
-                        left.Add(item.id);
-                        foreach (var x in item.currency.teacherAilities)
+                        x.children.ForEach(y =>
                         {
-                            string sqls = $" select value(c) from c  where c.abilityId='{x.id}' and c.code='AbilityTask-standard10'";
-                            List<AbilityTask> abilityTasks = new List<AbilityTask>();
-                            Dictionary<string, RecordFileAbility> valuePairs = new Dictionary<string, RecordFileAbility>();
-                            await foreach (var y in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).GetItemQueryIterator<AbilityTask>
-                                  (sqls, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"AbilityTask-standard10") }))
+                            y.rnodes.ForEach(r =>
                             {
-                                abilityTasks.Add(y);
-                            }
-                            //   double limit = 0;
-                            abilityTasks.ForEach(x =>
-                            {
-                                x.children.ForEach(y =>
-                                {
-                                    y.rnodes.ForEach(r =>
-                                    {
 
-                                        if (valuePairs.ContainsKey(r.hash))
-                                        {
-                                            valuePairs.TryGetValue(r.hash, out var value);
-                                            var ablt=  value.fileAbilities.Find(z => z.abilityId.Equals(x.abilityId) && z.taskId.Equals(x.id)  && z.nodeId.Equals(y.id) );
-                                            if (ablt == null) {
-                                                value.fileAbilities.Add(new FileAbility { url = r.link, abilityId = x.abilityId, taskId = x.id, nodeId = y.id });
-                                               // limit = limit + r.duration;
-                                            }
-                                        }
-                                        else
-                                        {
-                                            valuePairs.Add(r.hash, new RecordFileAbility
-                                            {
-                                                fileRecord =
-                                                new FileRecord { hash = r.hash, size = r.size.Value, duration = r.duration, view = (int)r.duration, type = r.type, done = true },
-                                                fileAbilities = new List<FileAbility> { new FileAbility { url = r.link, abilityId = x.abilityId, taskId = x.id, nodeId = y.id } }
-                                            });
-                                           // limit = limit + r.duration;
-                                        }
-                                    });
-                                });
-                            });
-
-                            foreach (var ps in valuePairs)
-                            {
-                                var fils = teacherFile.fileRecords.Find(x => x.hash.Equals(ps.Key));
-                                if (fils != null)
+                                if (valuePairs.ContainsKey(r.hash))
                                 {
-                                    ps.Value.fileAbilities.ForEach(x =>
+                                    valuePairs.TryGetValue(r.hash, out var value);
+                                    var ablt = value.fileAbilities.Find(z => z.abilityId.Equals(x.abilityId) && z.taskId.Equals(x.id) && z.nodeId.Equals(y.id));
+                                    if (ablt == null)
                                     {
-                                        var a = fils.files.Find(z => z.nodeId.Equals(x.nodeId) && z.abilityId.Equals(x.abilityId));
-                                        if (a == null)
-                                        {
-                                            fils.files.Add(new FileAbility { url = x.url, abilityId = x.abilityId, taskId = x.taskId, nodeId = x.nodeId });
-                                        }
-                                    });
+                                        value.fileAbilities.Add(new FileAbility { url = r.link, abilityId = x.abilityId, taskId = x.id, nodeId = y.id });
+                                        // limit = limit + r.duration;
+                                    }
                                 }
                                 else
                                 {
-                                    teacherFile.fileRecords.Add(new FileRecord
+                                    valuePairs.Add(r.hash, new RecordFileAbility
                                     {
-                                        hash = ps.Value.fileRecord.hash,
-                                        size = ps.Value.fileRecord.size,
-                                        duration = ps.Value.fileRecord.duration,
-                                        view = (int)ps.Value.fileRecord.view,
-                                        type = ps.Value.fileRecord.type,
-                                        done = true,
-                                        files = ps.Value.fileAbilities
+                                        fileRecord =
+                                        new FileRecord { hash = r.hash, size = r.size.Value, duration = r.duration, view = (int)r.duration, type = r.type, done = true },
+                                        fileAbilities = new List<FileAbility> { new FileAbility { url = r.link, abilityId = x.abilityId, taskId = x.id, nodeId = y.id } }
                                     });
+                                    // limit = limit + r.duration;
                                 }
-                            }
+                            });
+                        });
+                    });
+
+                    foreach (var ps in valuePairs)
+                    {
+                        var fils = teacherFile.fileRecords.Find(x => x.hash.Equals(ps.Key));
+                        if (fils != null)
+                        {
+                            ps.Value.fileAbilities.ForEach(x =>
+                            {
+                                var a = fils.files.Find(z => z.nodeId.Equals(x.nodeId) && z.abilityId.Equals(x.abilityId));
+                                if (a == null)
+                                {
+                                    fils.files.Add(new FileAbility { url = x.url, abilityId = x.abilityId, taskId = x.taskId, nodeId = x.nodeId });
+                                }
+                            });
+                        }
+                        else
+                        {
+                            teacherFile.fileRecords.Add(new FileRecord
+                            {
+                                hash = ps.Value.fileRecord.hash,
+                                size = ps.Value.fileRecord.size,
+                                duration = ps.Value.fileRecord.duration,
+                                view = (int)ps.Value.fileRecord.view,
+                                type = ps.Value.fileRecord.type,
+                                done = true,
+                                files = ps.Value.fileAbilities
+                            });
                         }
-                        teacherFile = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReplaceItemAsync<TeacherFile>(teacherFile, teacherFile.id, new PartitionKey(teacherFile.code));
-                        item.update.Add(StatisticsService.TeacherAbility);
-                        await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReplaceItemAsync<TeacherTrain>(item, item.id, new PartitionKey(item.code));
-                       
-                    }
-                    else {
-                        right.Add(item.id);
                     }
                 }
+                teacherFile = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReplaceItemAsync<TeacherFile>(teacherFile, teacherFile.id, new PartitionKey(teacherFile.code));
+                item.update.Add(StatisticsService.TeacherAbility);
+                await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReplaceItemAsync<TeacherTrain>(item, item.id, new PartitionKey(item.code));
             }
-            return Ok(new { right,left});
+            return Ok(new {});
         }
 
 
@@ -918,6 +915,9 @@ namespace TEAMModelOS.Controllers
             
             return Ok();
         }
+
+
+
         [HttpPost("fix-teacher-ability-files")]
         public async Task<IActionResult> TestScteacher(JsonElement json) {
             if (!json.TryGetProperty("ids", out JsonElement _ids)) return BadRequest();