public Yw_StudentTask CreateStudyPractice(Yw_StudentCourseProgress progress, int studentId, int lessonId, int lessonIndex, int lessonProgressId, List <int> subjectIds, StudyTaskTypeEnum taskType)
        {
            Yw_StudyTask st = new Yw_StudyTask();

            st.Ysk_ClassId          = progress.Yps_ClassId;
            st.Ysk_CourseId         = progress.Yps_CourseId;
            st.Ysk_CreateTime       = DateTime.Now;
            st.Ysk_ExpiredTime      = DateTime.Now.AddDays(7);
            st.Ysk_LessonId         = lessonId;
            st.Ysk_LessonIndex      = lessonIndex;
            st.Ysk_LessonProgressId = lessonProgressId;
            st.Ysk_SchoolId         = progress.Yps_SchoolId;
            st.Ysk_Score            = 0;
            st.Ysk_Status           = (int)StatusEnum.效;
            st.Ysk_SubjectCount     = subjectIds == null ? 0 : subjectIds.Count;
            st.Ysk_SubjectIds       = subjectIds == null ? "" : string.Join(",", subjectIds);
            st.Ysk_TaskType         = (int)taskType;
            st.Ysk_TeacherId        = 0;
            StudyTaskRepository.Add(st);

            Yw_StudentTask stk = new Yw_StudentTask();

            stk.Yuk_StudentId         = studentId;
            stk.Yuk_CourseId          = progress.Yps_CourseId;
            stk.Yuk_CreateTime        = DateTime.Now;
            stk.Yuk_StartTime         = new DateTime(1900, 1, 1);
            stk.Yuk_FinishTime        = new DateTime(1900, 1, 1);
            stk.Yuk_ExpiredTime       = DateTime.Now.AddDays(7);
            stk.Yuk_GainCoins         = 0;
            stk.Yuk_LessonId          = lessonId;
            stk.Yuk_LessonIndex       = lessonIndex;
            stk.Yuk_Percent           = 0;
            stk.Yuk_RightSubjectCount = 0;
            stk.Yuk_SchoolId          = progress.Yps_SchoolId;
            stk.Yuk_Status            = (int)StudentTaskStatusEnum.未开始;
            stk.Yuk_StudentScore      = 0;
            stk.Yuk_TaskId            = st.Ysk_Id;
            stk.Yuk_TaskType          = (int)taskType;
            stk.Yuk_SubjectCount      = subjectIds == null ? 0 : subjectIds.Count;
            StudentTaskRepository.Add(stk);

            return(stk);
        }
        /// <summary>
        /// 分批次返回课后任务的题目,每次返回10个题目数据
        /// </summary>
        public List <DtoSubjectContent> GetTaskSubject(int studyTaskId, int pageIndex, out int totalCount)
        {
            List <DtoSubjectContent> subjectContents = new List <DtoSubjectContent>();
            Yw_StudyTask             task            = StudyTaskRepository.Get(studyTaskId);

            string[] ids = task.Ysk_SubjectIds.Split(',');
            totalCount = ids.Length;
            if ((pageIndex - 1) * 10 < ids.Length)
            {
                var pageIds = ids.Skip((pageIndex - 1) * 10).Take(10).ToList();
                Dictionary <string, int> orderDic = pageIds.ToOrderDic();
                SubjectBll subjectBll             = new SubjectBll();
                subjectContents = subjectBll.GetCompleteContentsOfSubject(
                    pageIds.Select(x => Convert.ToInt32(x))).ToList();
                subjectContents = subjectContents.OrderBy(x => orderDic[x.SubjectId.ToString()]).ToList();
            }

            return(subjectContents);
        }
        /// <summary>
        /// 学生开始课后任务,生成题目
        /// </summary>
        public void GenerateTaskSubjectsAutoAfterStudy(int studyTaskId, int studentId)
        {
            StudentStudyBll studyBll   = new StudentStudyBll();
            SubjectBll      subjectBll = new SubjectBll();

            Yw_StudyTask   task    = StudyTaskRepository.Get(studyTaskId);
            Yw_StudentTask stuTask = StudentTaskRepository.GetByStudentTask(studentId, studyTaskId);

            if (task == null || stuTask == null)
            {
                return;
            }

            Yw_StudentLessonAnswerExt answer = studyBll.GetLessonAnswer(task.Ysk_LessonProgressId) as Yw_StudentLessonAnswerExt;

            if (answer == null)
            {
                return;
            }

            List <StudentAnswerBase> problemAnswers = answer.Yla_Answer_Obj.SelectMany(x => x.AnswerCollection).Where(x => x.ResultStars < 5).ToList();
            List <Tuple <int, int> > errorSubjects  = problemAnswers.GroupBy(x => x.SubjectId).
                                                      Select(x => new Tuple <int, int>(x.Key, x.Min(y => y.ResultStars))).ToList();

            List <DtoLesTaskSubject> subjects = subjectBll.GetLessonTaskSubject(task.Ysk_LessonId, errorSubjects);

            var groups = subjects.OrderBy(x => x.Number)
                         .GroupBy(x => new { ErrorSubjectId = x.ErrorSubjectId, Score = x.Score })
                         .OrderBy(x => x.Key.Score);

            Dictionary <int, DtoLesTaskSubject> subjectSelected = new Dictionary <int, DtoLesTaskSubject>();

            List <WrapSubjectGroup> wrapGroups = new List <WrapSubjectGroup>();

            foreach (IGrouping <dynamic, DtoLesTaskSubject> group in groups)
            {
                wrapGroups.Add(new WrapSubjectGroup(group.Key.Score, group.ToList()));
            }

            bool hasSubject      = false;
            bool reachMax        = false;
            int  maxSubjectCount = groups.Count() > 50 ? groups.Count() : 50;//每个错题至少推一个关联题目
            int  loopTime        = 0;

            while (loopTime < maxSubjectCount)
            {
                hasSubject = false;
                foreach (WrapSubjectGroup group in wrapGroups)
                {
                    bool result = group.TakeSubject(subjectSelected);
                    if (result)
                    {
                        if (subjectSelected.Count >= maxSubjectCount)
                        {
                            reachMax = true;
                            break;
                        }
                        hasSubject = true;
                    }
                }
                if (!hasSubject || reachMax)
                {
                    break;
                }
                loopTime++;
            }

            if (subjectSelected.Count > 0)
            {
                task.Ysk_SubjectIds   = string.Join(",", subjectSelected.OrderBy(x => x.Value.SubjectType).Select(x => x.Value.SubjectId));
                task.Ysk_SubjectCount = subjectSelected.Count;
                task.Ysk_Score        = 5 * subjectSelected.Count;
                StudyTaskRepository.Update(task);

                stuTask.Yuk_SubjectCount = subjectSelected.Count;
                StudentTaskRepository.Update(stuTask);
            }
        }
        /// <summary>
        /// 保存课后任务或者练习题答案
        /// </summary>
        public void SaveResult(int studentId, int taskId, int useTime, List <StudentAnswerBase> answers, StudyTaskTypeEnum taskType = 0, int partId = 0)
        {
            Yw_StudentTask stk = StudentTaskRepository.GetByStudentTask(studentId, taskId);

            if (stk.Yuk_Status == (int)StudentTaskStatusEnum.已完成)
            {
                throw new AbhsException(ErrorCodeEnum.StudentTaskStatusInvalid, AbhsErrorMsg.ConstStudentTaskStatusInvalid);
            }

            int totalStars       = answers.Sum(x => x.ResultStars);
            int totalCoins       = CalcCoins(answers);
            int fiveStarsAnswers = answers.Count(x => x.ResultStars == 5);

            var finishTime = DateTime.Now;

            //更新学生任务记录表

            stk.Yuk_StartTime         = finishTime.AddSeconds(0 - useTime);//反算时间
            stk.Yuk_FinishTime        = finishTime;
            stk.Yuk_StudentScore      = totalStars;
            stk.Yuk_GainCoins         = totalCoins;
            stk.Yuk_RightSubjectCount = fiveStarsAnswers;

            if (answers.Count > 0)
            {
                stk.Yuk_Percent = (int)(Math.Round(fiveStarsAnswers * 1.0 / answers.Count, 2) * 100);
            }

            stk.Yuk_Status = (int)StudentTaskStatusEnum.已完成;
            StudentTaskRepository.Update(stk);

            StudentAnswerCard card = new StudentAnswerCard();

            card.UseTime          = useTime;
            card.SubmitTime       = finishTime.ToString("yyyy-MM-dd HH:mm:ss");
            card.Part             = partId;
            card.AnswerCollection = answers;
            card.TotalStars       = totalStars;
            card.TotalCoins       = totalCoins;

            //学生任务答题结果
            Yw_StudentStudyTaskAnswerExt answer = new Yw_StudentStudyTaskAnswerExt();

            answer.Yta_StudentId          = studentId;
            answer.Yta_StudentStudyTaskId = stk.Yuk_Id;
            answer.Yta_TaskId             = taskId;
            answer.Yta_Answer_Obj         = card;
            answer.Yta_CreateTime         = DateTime.Now;
            StuStudyTaskAnsRepo.Add(answer);

            //学生最近答题记录
            Yw_StudyTask task       = StudyTaskRepository.Get(taskId);
            StudentBll   studentBll = new StudentBll();
            List <int>   ids        = task.Ysk_SubjectIds.Split(',').Select(x => Convert.ToInt32(x)).ToList();

            studentBll.RefreshStudentRecentSubject(studentId, ids);

            StudentInfoBll bll = new StudentInfoBll();

            bll.AddCoins(studentId, totalCoins);

            if (taskType == StudyTaskTypeEnum.系统课后任务)
            {
                new StudentPracticeBll().PublishStudyTaskMessage(
                    task.Ysk_CourseId,
                    task.Ysk_LessonId,
                    studentId,
                    useTime,
                    answers.Count,
                    totalCoins);
            }
            else if (taskType == StudyTaskTypeEnum.课后练习)
            {
                new StudentPracticeBll().PublishStudyPractiseMessage(
                    task.Ysk_CourseId,
                    task.Ysk_LessonId,
                    studentId,
                    useTime,
                    answers.Count,
                    totalCoins);
            }

            //课程学习 = 1, 课后任务 = 2, 课后练习 = 3
            StudyWrongSourceEnum?source = null;

            switch (taskType)
            {
            case StudyTaskTypeEnum.系统课后任务:
            case StudyTaskTypeEnum.老师课后任务:
                source = StudyWrongSourceEnum.课后任务;
                break;

            case StudyTaskTypeEnum.课后练习:
                source = StudyWrongSourceEnum.课后练习;
                break;

            default:
                source = StudyWrongSourceEnum.课后任务;
                break;
            }
            new StudentWrongBookBll().SaveWrongBook(
                new List <StudentAnswerCard> {
                card
            },
                new DtoStudentWrongBook
            {
                CourseId         = task.Ysk_CourseId,
                LessonId         = task.Ysk_LessonId,
                LessonProgressId = task.Ysk_LessonProgressId,
                Source           = source.Value,
                StudentId        = studentId,
                StudyTaskId      = taskId
            });
        }