/// <summary>
        /// 单选题解析
        /// 解析用户回答,获取下一题
        /// </summary>
        /// <param name="uanswer">用户答题对象</param>
        /// <param name="question">问题对象</param>
        /// <param name="answer">用户答案文本</param>
        /// <returns>下一题</returns>
        private WeiExecuteResult SingleCheckAnalysis(UserAnswerDetail uanswer, Question question, UserAnswerDetail nuseranswerdetail)
        {
            decimal?next   = null; // decimal.Floor(question.Sort + 1);
            var     qalist = question.QuestionAnswerList.OrderBy(x => x.Sort);

            string answer = DataConvertHelper.ChineseNumberAnalysis(uanswer.Answer).ToLower();

            if (!question.QuestionItemList.Any(x => answer.IndexOf(x.Code.ToLower()) != -1))
            {
                return(WeiExecuteResultHelper.Failed(this._propertyService.GetValue("Answer.NotConsistent")));
            }

            string         keycode = null;
            QuestionAnswer qamodel = null;

            foreach (var qanswer in qalist)
            {
                var tmpQ = qanswer.AnswerKeys.ToLower().Split('|');
                keycode = tmpQ.FirstOrDefault(y =>
                {
                    if (string.IsNullOrEmpty(y))
                    {
                        return(false);
                    }
                    if (y == "*")
                    {
                        return(true);
                    }

                    var tmp2    = y.ToLower().Split('&');
                    bool result = !tmp2.Any(z => answer.IndexOf(z) == -1);
                    return(result);
                });
                if (!string.IsNullOrEmpty(keycode))
                {
                    qamodel = qanswer;
                    break;
                }
            }

            //if (qamodel == null)
            //{
            //    return WeiExecuteResultHelper.Failed(this._propertyService.GetValue("Answer.NotConsistent"));
            //}

            if (qamodel != null)
            {
                nuseranswerdetail.QCode = keycode;
                //if (qamodel.Next != null)
                next = qamodel.Next;
            }
            else
            {
                next = decimal.Floor(question.Sort + 1);
            }

            return(WeiExecuteResultHelper.Success(null, next));
        }
 /// <summary>
 /// 提示符答题
 /// </summary>
 /// <param name="uanswer"></param>
 /// <param name="question"></param>
 /// <returns></returns>
 private WeiExecuteResult TipsAnalysis(UserAnswerDetail uanswer, Question question, UserAnswerDetail nuseranswerdetail)
 {
     //decimal next = decimal.Floor(question.Sort + 1);
     //if (this._propertyService.CheckCodeValue("Answer.Suspend", uanswer.Answer)) // (string.Equals(uanswer.Answer, "终止")
     //    //|| string.Equals(uanswer.Answer, "N", StringComparison.CurrentCultureIgnoreCase))
     //{
     //    uanswer.UserAnswer.UserAnswerStatus = UserAnswerStatus.挂起;
     //    return WeiExecuteResultHelper.Failed(this._propertyService.GetValue("Answer.SuspendTips"));
     //}
     //if (this._propertyService.CheckCodeValue("Answer.Continue", uanswer.Answer)) // (string.Equals(uanswer.Answer, "继续")
     //   // || string.Equals(uanswer.Answer, "Y", StringComparison.CurrentCultureIgnoreCase))
     //{
     return(WeiExecuteResultHelper.Success());
     //}
     //return WeiExecuteResultHelper.Failed(this._propertyService.GetValue("Answer.NotConsistent"));
 }
        /// <summary>
        /// 保存答案并获取下一题
        /// </summary>
        /// <param name="uanswer"></param>
        /// <param name="answer"></param>
        /// <returns></returns>
        public Question SaveAnswer(UserAnswer uanswer, string answer, User user, MediaType mediaType = MediaType.None, string mediaContent = null)
        {
            var uanswerdetail = uanswer.UserAnswerDetailList.FirstOrDefault(x => x.End == null);

            if (uanswerdetail == null)
            {
                uanswer.CompletedTime    = DateTime.Now;
                uanswer.UserAnswerStatus = UserAnswerStatus.答题完成;
                this._userAnswerRepository.Update(uanswer);
                return(new Question()
                {
                    Text = this._propertyService.GetValue("Answer.Complete"),
                    AnswerType = AnswerType.End
                });
            }
            // 超过两小时,自动挂起
            if (DateTime.Now.AddHours(-2) > uanswerdetail.Start)
            {
                uanswer.UserAnswerStatus = UserAnswerStatus.挂起;
                this._userAnswerRepository.Update(uanswer);
                return(new Question()
                {
                    AnswerType = AnswerType.Text,
                    Text = this._propertyService.GetValue("Answer.Timeout")
                });
            }
            // 获取当前题目
            var question       = this._questionBankService.GetQuestion(uanswerdetail.UserAnswer.QuestionBank_Id, uanswerdetail.QuestionNo);
            var nuanswerdetail = new UserAnswerDetail();

            // 语音答题处理文本数据
            if (mediaType == MediaType.Voice)
            {
                answer = CorrectAnswer(answer, uanswerdetail.UserAnswer.QuestionBank_Id);
            }

            //decimal nextQ = 0;
            WeiExecuteResult analysisQResult = null;

            // 文本答题,判断是否为下一题
            if (question.AnswerType == AnswerType.Text && this._propertyService.CheckCodeValue("Answer.Next", answer)) // (answer.Length < 20 && answer.IndexOf("下一题") != -1))
            {
                // 文本题,跳转下一题
                uanswerdetail.End = DateTime.Now;
                analysisQResult   = this.TextAnalysis(uanswerdetail, question, nuanswerdetail);
            }
            else
            {
                // 保存语音
                if (mediaType != MediaType.None)
                {
                    // 写入多媒体答案
                    var mediaObj = new UserAnswerDetail_Media()
                    {
                        MediaType           = mediaType,
                        CreateTime          = DateTime.Now,
                        MediaContent        = mediaContent,
                        Text                = answer,
                        UserAnswerDetail_Id = uanswerdetail.Id
                    };
                    this.SaveUserAnswerDetailMedia(mediaObj);
                }

                answer = answer.ToLower();
                // 判断当前答案
                switch (question.AnswerType)
                {
                case AnswerType.SingleCheck:
                    uanswerdetail.Answer = answer;
                    analysisQResult      = this.SingleCheckAnalysis(uanswerdetail, question, nuanswerdetail);
                    break;

                case AnswerType.MultiCheck:
                    uanswerdetail.Answer = answer;
                    analysisQResult      = this.MultiCheckAnalysis(uanswerdetail, question, nuanswerdetail);
                    break;

                case AnswerType.Tips:
                    analysisQResult = this.TipsAnalysis(uanswerdetail, question, nuanswerdetail);
                    break;

                default:
                    if (uanswerdetail.Answer == null)
                    {
                        uanswerdetail.Answer = answer;
                    }
                    else
                    {
                        uanswerdetail.Answer += answer;
                    }
                    analysisQResult = WeiExecuteResultHelper.Failed(this._propertyService.GetValue("Answer.TextTips", 1));
                    break;
                }
            }

            Question nextqObj = null;

            if (analysisQResult.Success)
            {
                decimal nextqno = analysisQResult.Obj.ToDecimal();
                nextqObj = this.NextQuestion(uanswer, question, nextqno, nuanswerdetail);
            }
            else
            {
                nextqObj = new Question()
                {
                    AnswerType = AnswerType.Text,
                    Text       = analysisQResult.Message
                };
            }
            //switch (nextQ)
            //{
            //    case 0:
            //        nextqObj = new Question()
            //        {
            //            AnswerType = AnswerType.Text,
            //            Text = "您可以继续追加回答,或者告诉我“下一题”保存答案!"
            //        };
            //        break;
            //    case -1:
            //        nextqObj = new Question()
            //        {
            //            AnswerType = AnswerType.Text,
            //            Text = "您的回答似乎不符,请尝试重新作答!"
            //        };
            //        break;
            //    case -2:
            //        uanswer.UserAnswerStatus = UserAnswerStatus.挂起;
            //        nextqObj = new Question()
            //        {
            //            AnswerType = AnswerType.Text,
            //            Text = $"答题已暂停,在有效期内({uanswer.QuestionBank.ExpireDateEnd.Value.ToString("yyyyMMdd")})对我说题卷关键字可以继续作答。谢谢您的参与!"
            //        };
            //        break;
            //    default:
            //        nextqObj = this._questionBankService.GetQuestion(uanswer.QuestionBank_Id, nextQ);
            //        break;
            //}

            if (nextqObj != null)
            {
                // 判断是否是最后一题
                switch (nextqObj.AnswerType)
                {
                case AnswerType.End:
                    uanswerdetail.Next       = 0;
                    nuanswerdetail.End       = DateTime.Now;
                    uanswer.CompletedTime    = DateTime.Now;
                    uanswer.UserAnswerStatus = UserAnswerStatus.答题完成;
                    break;

                case AnswerType.Break:
                    uanswer.CompletedTime    = DateTime.Now;
                    nuanswerdetail.End       = DateTime.Now;
                    uanswer.UserAnswerStatus = UserAnswerStatus.已作废;
                    break;

                //case AnswerType.Tips:
                //    Task task = new Task(() =>
                //    {
                //        _logger.Information("before begin task");
                //        System.Threading.Thread.Sleep(500);
                //        _logger.Information("begin task");
                //        try
                //        {
                //            SaveAnswer(uanswer, "", user);
                //        }
                //        catch(Exception ex)
                //        {
                //            _logger.Error(ex.Message, ex);
                //        }
                //        _logger.Information("begin task");
                //    });
                //    task.Start();
                //    break;
                default:
                    if (nextqObj.Id > 0)
                    {
                        uanswerdetail.Next = nextqObj.Sort;
                        uanswerdetail.End  = DateTime.Now;

                        nuanswerdetail.QuestionNo = nextqObj.Sort;
                        nuanswerdetail.Start      = DateTime.Now;
                        uanswer.UserAnswerDetailList.Add(nuanswerdetail);
                    }
                    break;
                }
                this._userAnswerRepository.Update(uanswer);
                return(nextqObj);
            }
            return(null);
        }
        /// <summary>
        /// 简答题解析
        /// 解析用户回答,获取下一题
        /// </summary>
        /// <param name="uanswer">用户答题对象</param>
        /// <param name="question">问题对象</param>
        /// <param name="answer">用户答案文本</param>
        /// <returns>下一题 (-2:挂起; -1:重新回答; 0:不做反馈; >0:获取题目)</returns>
        private WeiExecuteResult TextAnalysis(UserAnswerDetail uanswer, Question question, UserAnswerDetail nuseranswerdetail)
        {
            decimal?       next    = null;
            string         answer  = uanswer.Answer.ToLower();
            var            qalist  = question.QuestionAnswerList.OrderBy(x => x.Sort);
            string         keycode = null;
            QuestionAnswer qamodel = null;

            switch (question.MatchingType)
            {
            case MatchingType.Multiple:
            {
                foreach (var qanswer in qalist)
                {
                    var tmpQ = qanswer.AnswerKeys.ToLower().Split('|');
                    keycode = tmpQ.FirstOrDefault(y =>
                        {
                            if (string.IsNullOrEmpty(y) || y == "*")
                            {
                                return(true);
                            }

                            var tmp2    = y.ToLower().Split('&');
                            bool result = !tmp2.Any(z => answer.IndexOf(z) == -1);
                            return(result);
                        });
                    if (!string.IsNullOrEmpty(keycode))
                    {
                        UserAnswerQueue uaqueue = new UserAnswerQueue()
                        {
                            QuestionAnswer_Id = qanswer.Id,
                            UserAnswer_Id     = uanswer.UserAnswer_Id,
                            Status            = 0,
                            QCode             = keycode
                        };
                        this._userAnswerQueueRepository.Insert(uaqueue);
                    }
                }
            }
            break;

            default:
            {
                foreach (var qanswer in qalist)
                {
                    var tmpQ = qanswer.AnswerKeys.ToLower().Split('|');
                    keycode = tmpQ.FirstOrDefault(y =>
                        {
                            if (string.IsNullOrEmpty(y) || y == "*")
                            {
                                return(true);
                            }

                            var tmp2    = y.ToLower().Split('&');
                            bool result = !tmp2.Any(z => answer.IndexOf(z) == -1);
                            return(result);
                        });
                    if (!string.IsNullOrEmpty(keycode))
                    {
                        qamodel = qanswer;
                        break;
                    }
                }
            }
            break;
            }

            if (qamodel != null)
            {
                nuseranswerdetail.QCode = keycode;
                next = qamodel.Next;
            }
            return(WeiExecuteResultHelper.Success(null, next));
        }
        /// <summary>
        /// 多选题解析
        /// 解析用户回答,获取下一题
        /// </summary>
        /// <param name="uanswer">用户答题对象</param>
        /// <param name="question">问题对象</param>
        /// <param name="answer">用户答案文本</param>
        /// <returns>下一题</returns>
        private WeiExecuteResult MultiCheckAnalysis(UserAnswerDetail uanswer, Question question, UserAnswerDetail nuseranswerdetail)
        {
            decimal?next = null; // decimal.Floor(question.Sort + 1);
            // 用户的答案数组
            //var tmpU = uanswer.Answer.ToCharArray().Distinct().Except(CommonHelper.SPECIALCHARACTERS);
            var qalist = question.QuestionAnswerList.OrderBy(x => x.Sort);

            string answer = DataConvertHelper.ChineseNumberAnalysis(uanswer.Answer).ToLower();

            if (!question.QuestionItemList.Any(x => answer.IndexOf(x.Code.ToLower()) != -1))
            {
                return(WeiExecuteResultHelper.Failed(this._propertyService.GetValue("Answer.NotConsistent")));
            }

            string         keycode = null;
            QuestionAnswer qamodel = null;

            switch (question.MatchingType)
            {
            case MatchingType.Multiple:
            {
                foreach (var qanswer in qalist)
                {
                    var tmpQ = qanswer.AnswerKeys.ToLower().Split('|');

                    keycode = tmpQ.FirstOrDefault(y =>
                        {
                            if (string.IsNullOrEmpty(y))
                            {
                                return(false);
                            }
                            if (y == "*")
                            {
                                return(true);
                            }

                            var tmp2    = y.ToLower().Split('&');
                            bool result = !tmp2.Any(z => answer.IndexOf(z) == -1);
                            return(result);
                        });
                    if (!string.IsNullOrEmpty(keycode))
                    {
                        UserAnswerQueue uaqueue = new UserAnswerQueue()
                        {
                            QuestionAnswer_Id = qanswer.Id,
                            UserAnswer_Id     = uanswer.UserAnswer_Id,
                            Status            = 0,
                            QCode             = keycode
                        };
                        this._userAnswerQueueRepository.Insert(uaqueue);
                    }
                }
            }
            break;

            default:
            {
                foreach (var qanswer in qalist)
                {
                    var tmpQ = qanswer.AnswerKeys.ToLower().Split('|');

                    keycode = tmpQ.FirstOrDefault(y =>
                        {
                            if (string.IsNullOrEmpty(y))
                            {
                                return(false);
                            }
                            if (y == "*")
                            {
                                return(true);
                            }

                            var tmp2    = y.ToLower().Split('&');
                            bool result = !tmp2.Any(z => answer.IndexOf(z) == -1);
                            return(result);
                        });
                    if (!string.IsNullOrEmpty(keycode))
                    {
                        qamodel = qanswer;
                        break;
                    }
                }
            }
            break;
            }

            //if (qamodel == null)
            //{
            //    return WeiExecuteResultHelper.Failed(this._propertyService.GetValue("Answer.NotConsistent"));
            //}
            if (qamodel != null)
            {
                nuseranswerdetail.QCode = keycode;
                //if (qamodel.Next != null)
                next = qamodel.Next;
            }
            else
            {
                next = decimal.Floor(question.Sort + 1);
            }

            //nuseranswerdetail.QCode = keycode;
            //next = qamodel.Next;

            return(WeiExecuteResultHelper.Success(null, next));
        }