using DocumentFormat.OpenXml.Spreadsheet;
using Hotline.Application.Bulletin;
using Hotline.Application.OrderApp;
using Hotline.Article;
using Hotline.Caching.Interfaces;
using Hotline.Configurations;
using Hotline.KnowledgeBase;
using Hotline.Orders;
using Hotline.Push.Notifies;
using Hotline.Repository.SqlSugar.Extensions;
using Hotline.Repository.SqlSugar.Knowledge;
using Hotline.SeedData;
using Hotline.Settings;
using Hotline.Settings.Hotspots;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.DataSharing.PusherHotlineDto;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Dtos.Schedulings;
using Hotline.Share.Dtos.WebPortal;
using Hotline.Share.Enums.KnowledgeBase;
using Hotline.Share.Enums.Order;
using Hotline.Share.Enums.Push;
using Hotline.WebPortal;
using MapsterMapper;
using MathNet.Numerics;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Senparc.Weixin.WxOpen.AdvancedAPIs.WxApp.WxAppJson;
using SqlSugar;
using XF.Domain.Authentications;
using XF.Domain.Cache;
using XF.Domain.Filters;
using XF.Domain.Repository;

namespace Hotline.Api.Controllers
{
    public class WebPortalController : BaseController
    {
        #region 注入

        private readonly IMapper _mapper;
        private readonly IMediator _mediator;
        private readonly IRepository<Bulletin> _bulletinRepository;
        private readonly IRepository<WebUserRegister> _webUserRegisterRepository;
        private readonly IRepository<WebUserAuth> _webUserAuthRepository;
        private readonly IRepository<WebFlowAccept> _webFlowAcceptRepository;
        private readonly ITypedCache<WriteLettersSendSmsDto> _writeLettersSendSms;
        private readonly IRepository<Hotspot> _hotspotRepository;
        private readonly ISystemSettingCacheManager _systemSettingCacheManager;
        private readonly IRepository<OrderPublish> _orderPublishRepository;
        private readonly IOrderRepository _orderRepository;
        private readonly IRepository<OrderVisit> _orderVisitRepository;
        private readonly IOrderApplication _orderApplication;
        private readonly ISessionContext _sessionContext;
        private readonly IRepository<OrderVisitDetail> _orderVisitDetailRepository;
        private readonly IBulletinApplication _bulletinApplication;
        private readonly IRepository<OldPublicData> _oldPublicDataRepository;
        private readonly IRepository<KnowledgeType> _knowledgeTypeRepository;
        private readonly IRepository<Knowledge> _knowledgeRepository;
        private readonly ISystemDicDataCacheManager _systemDicDataCacheManager;
        private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
        private readonly ITypedCache<string> _getVailData;
        private readonly IRepository<KnowledgeWord> _knowledgeWordRepository;
        private readonly ISystemDicDataCacheManager _sysDicDataCacheManager;

        public WebPortalController(IMapper mapper,
            IMediator mediator,
            IRepository<Bulletin> bulletinRepository,
            IRepository<WebUserRegister> webUserRegisterRepository,
            IRepository<WebUserAuth> webUserAuthRepository,
            IRepository<WebFlowAccept> webFlowAcceptRepository,
            ITypedCache<WriteLettersSendSmsDto> writeLettersSendSms,
            IRepository<Hotspot> hotspotRepository,
            ISystemSettingCacheManager systemSettingCacheManager,
            IRepository<OrderPublish> orderPublishRepository,
            IOrderRepository orderRepository,
            IRepository<OrderVisit> orderVisitRepository,
            IOrderApplication orderApplication,
            ISessionContext sessionContext,
            IRepository<OrderVisitDetail> orderVisitDetailRepository,
            IBulletinApplication bulletinApplication,
            IRepository<OldPublicData> oldPublicDataRepository,
            IRepository<KnowledgeType> knowledgeTypeRepository,
            IRepository<Knowledge> knowledgeRepository,
            ISystemDicDataCacheManager systemDicDataCacheManager,
            IOptionsSnapshot<AppConfiguration> appOptions,
            ITypedCache<string> getVailData,
            IRepository<KnowledgeWord> knowledgeWordRepository,
            ISystemDicDataCacheManager sysDicDataCacheManager
            )
        {
            _mapper = mapper;
            _mediator = mediator;
            _bulletinRepository = bulletinRepository;
            _webUserRegisterRepository = webUserRegisterRepository;
            _webUserAuthRepository = webUserAuthRepository;
            _webFlowAcceptRepository = webFlowAcceptRepository;
            _writeLettersSendSms = writeLettersSendSms;
            _hotspotRepository = hotspotRepository;
            _systemSettingCacheManager = systemSettingCacheManager;
            _orderPublishRepository = orderPublishRepository;
            _orderRepository = orderRepository;
            _orderVisitRepository = orderVisitRepository;
            _orderApplication = orderApplication;
            _sessionContext = sessionContext;
            _orderVisitDetailRepository = orderVisitDetailRepository;
            _bulletinApplication = bulletinApplication;
            _oldPublicDataRepository = oldPublicDataRepository;
            _knowledgeTypeRepository = knowledgeTypeRepository;
            _knowledgeRepository = knowledgeRepository;
            _systemDicDataCacheManager = systemDicDataCacheManager;
            _appOptions = appOptions;
            _getVailData = getVailData;
            _knowledgeWordRepository = knowledgeWordRepository;
            _sysDicDataCacheManager = sysDicDataCacheManager;
        }

        #endregion

        #region 通知
        /// <summary>
        /// 获取列表
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getarticlelist")]
        public async Task<OpenResponse> GetArticleList([FromBody] QueryArticleListDto dto)
        {
            if (string.IsNullOrEmpty(dto.PushRanges))
                dto.PushRanges = "2";

            RefAsync<int> total = 0;
            var items = await _bulletinRepository.Queryable()
                .Where(p => p.LoseEfficacyTime >= DateTime.Now)
                .Where(p => p.IsArrive == true)
                .Where(p => SqlFunc.JsonListObjectAny(p.PushRanges, "Key", dto.PushRanges))
                 .Where(p => p.BulletinTypeId == dto.NoticeType)
                 .WhereIF(!string.IsNullOrEmpty(dto.Condition), p => p.Title.Contains(dto.Condition))
                 .OrderByDescending(p => p.CreationTime)
                 .Select(it => new
                 {
                     Page = SqlFunc.RowNumber($"{it.CreationTime} desc "),// SqlFunc.MappingColumn(default(int), "  row_number()  over( order by 'NoticeCreateDate'  ) "),
                     NoticeID = it.Id,
                     NoticeContent = it.Content,
                     NoticeTypeName = it.BulletinTypeName,
                     NoticeTitle = it.Title,
                     NoticeBMName = it.SourceOrgName,
                     NoticeCreateDate = it.CreationTime,
                     VideoUrl = "",
                     WNLT_FullCode = ""
                 })
                .ToPageListAsync(dto.PageIndex, dto.PageSize, total);

            //计算总页数
            int nPageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(total) / dto.PageSize));
            ArticleListDataDto dataDto = new()
            {
                PageCount = nPageCount,
                Total = total,
                data = _mapper.Map<IReadOnlyList<ArticleListDto>>(items)
            };

            return OpenResponse.Ok(WebPortalDeResponse<ArticleListDataDto>.Success(dataDto));
        }

        /// <summary>
        /// 获取通知公告前几条数据
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getarticlelistbynum")]
        public async Task<OpenResponse> GetArticleListByNum([FromBody] ArticleIdByNumDto dto)
        {
            if (string.IsNullOrEmpty(dto.PushRanges))
                dto.PushRanges = "2";

            var items = await _bulletinRepository.Queryable()
                .Where(p => p.LoseEfficacyTime >= DateTime.Now)
                .Where(p => p.IsArrive == true)
                .Where(p => SqlFunc.JsonListObjectAny(p.PushRanges, "Key", dto.PushRanges))
                //  .Where(p => p.BulletinTypeId == dto.BulletinTypeId)
                .WhereIF(!string.IsNullOrEmpty(dto.BulletinTypeId), p => p.BulletinTypeId == dto.BulletinTypeId)
                .WhereIF(!string.IsNullOrEmpty(dto.CheckChar), p => p.Content.Contains(dto.CheckChar))
                .WhereIF(!string.IsNullOrEmpty(dto.BulletinDisplayLocation), p => SqlFunc.JsonListObjectAny(p.DisplayLocation, "Key", dto.BulletinDisplayLocation))
                .OrderByDescending(p => p.CreationTime)
                .Select(it => new
                {
                    DataID = it.Id,
                    it.Title,
                    CreateDate = it.CreationTime,
                    it.Content,
                    it.BulletinTypeName
                })
                .Take(dto.Num)
                .ToListAsync();

            var data = _mapper.Map<IReadOnlyList<DataListTopDto>>(items);
            return OpenResponse.Ok(WebPortalDeResponse<IReadOnlyList<DataListTopDto>>.Success(data, "成功"));
        }

        /// <summary>
        /// 获取详情，修改阅读次数
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getarticledetails")]
        public async Task<OpenResponse> GetArticleDetails([FromBody] ArticleIdDto dto)
        {
            var data = await _bulletinRepository.GetAsync(p => p.Id == dto.Id, HttpContext.RequestAborted);
            ArticleDetailsDto detailsDto = null;
            if (data != null)
            {
                data.ReadedNum = data.ReadedNum++;
                await _bulletinRepository.UpdateAsync(data, HttpContext.RequestAborted);

                detailsDto = new()
                {
                    NoticeID = data.Id,
                    NoticeTypeName = data.BulletinTypeName,
                    NoticeTitle = data.Title,
                    NoticeBMName = data.SourceOrgName,
                    NoticeCreateDate = data.CreationTime,
                    NoticeRCount = data.ReadedNum,
                    WNED_VideoUrl = "",
                    NoticeContent = data.Content
                };

                if (data != null && !string.IsNullOrEmpty(data.Content))
                    data.Content = _bulletinApplication.GetSiteUrls(data.Content);
            }
            else
                detailsDto = new();
            List<ArticleDetailsDto> dataDto = new() { detailsDto };
            return OpenResponse.Ok(WebPortalDeResponse<IReadOnlyList<ArticleDetailsDto>>.Success(dataDto));
        }

        /// <summary>
        /// 根据分类获取详情
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getarticledetailsbytype")]
        public async Task<OpenResponse> GetArticleDetailsByType([FromBody] ArticleIdByNumDto dto)
        {
            var items = await _bulletinRepository.Queryable()
                .WhereIF(!string.IsNullOrEmpty(dto.BulletinTypeId), p => p.BulletinTypeId == dto.BulletinTypeId)
                .OrderByDescending(p => p.CreationTime)
                .Take(dto.Num)
                .ToListAsync();
            List<ArticleDetailsDto> dataDto = [];
            if (items != null && items.Any())
            {
                foreach (var item in items)
                {
                    if (!string.IsNullOrEmpty(item.Content))
                        item.Content = _bulletinApplication.GetSiteUrls(item.Content);

                    dataDto.Add(new()
                    {
                        NoticeID = item.Id,
                        NoticeTypeName = item.BulletinTypeName,
                        NoticeTitle = item.Title,
                        NoticeBMName = item.SourceOrgName,
                        NoticeCreateDate = item.CreationTime,
                        NoticeRCount = item.ReadedNum,
                        WNED_VideoUrl = "",
                        NoticeContent = item.Content
                    });
                }
            }
            return OpenResponse.Ok(WebPortalDeResponse<IReadOnlyList<ArticleDetailsDto>>.Success(dataDto));

        }

        /// <summary>
        /// 上一条和下一条
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getpreviousandnext")]
        public async Task<OpenResponse> GetPreviousAndNext([FromBody] ArticlePreviousAndNextDto dto)
        {
            if (string.IsNullOrEmpty(dto.PushRanges))
                dto.PushRanges = "2";

            var sugar = _bulletinRepository.Queryable()
                .Where(p => p.LoseEfficacyTime >= DateTime.Now)
                 .Where(p => p.IsArrive == true)
                .Where(p => SqlFunc.JsonListObjectAny(p.PushRanges, "Key", dto.PushRanges))
                ;
            if (dto.FullSearch == "1")//全文搜索
            {
                if (_appOptions.Value.IsYiBin)
                {
                    sugar.Where(p => p.BulletinTypeId == "1" || p.BulletinTypeId == "5" || p.BulletinTypeId == "6" || p.BulletinTypeId == "7" || p.BulletinTypeId == "3" || p.BulletinTypeId == "4")
                    .WhereIF(!string.IsNullOrEmpty(dto.Condition), p => p.Content.Contains(dto.Condition) || p.Title.Contains(dto.Condition));
                }
                if (_appOptions.Value.IsZiGong)
                {
                    sugar.Where(p => p.BulletinTypeId == "5013" || p.BulletinTypeId == "5016" || p.BulletinTypeId == "5011" || p.BulletinTypeId == "5015" || p.BulletinTypeId == "5017")
                    .WhereIF(!string.IsNullOrEmpty(dto.Condition), p => p.Content.Contains(dto.Condition) || p.Title.Contains(dto.Condition));
                }
            }
            else//指定分类
            {
                sugar.WhereIF(!string.IsNullOrEmpty(dto.Condition), p => p.Title.Contains(dto.Condition))
                    .Where(p => p.BulletinTypeId == dto.NoticeTypeId);
            }

            var list = await sugar.OrderByDescending(p => p.CreationTime)
                .Select(it => new
                {
                    Page = SqlFunc.RowNumber($"{it.CreationTime} desc "),// SqlFunc.MappingColumn(default(int), "  row_number()  over( order by 'NoticeCreateDate'  ) "),
                    NoticeID = it.Id,
                    NoticeTitle = it.Title,
                    NoticeCreateDate = it.CreationTime
                })
                .ToListAsync();
            //数据为空返回空数据
            if (list == null || list.Count == 0)
                return OpenResponse.Ok(WebPortalDeResponse<List<ArticlePreviousAndNextDataDto>>.Success(null));
            else
            {
                var temp = list.Find(p => p.NoticeID == dto.ID);
                if (temp != null)
                {
                    List<ArticlePreviousAndNextDataDto> returnDto = new();
                    //上一条
                    var pTemp = list.Find(p => p.Page == temp.Page - 1);
                    if (pTemp != null)

                        returnDto.Add(new()
                        {
                            NoticeID = pTemp.NoticeID,
                            NoticeTitle = pTemp.NoticeTitle,
                            pntype = "p"
                        });

                    //下一条
                    var nTemp = list.Find(p => p.Page == temp.Page + 1);
                    if (nTemp != null)
                        returnDto.Add(new()
                        {
                            NoticeID = nTemp.NoticeID,
                            NoticeTitle = nTemp.NoticeTitle,
                            pntype = "n"
                        });
                    return OpenResponse.Ok(WebPortalDeResponse<List<ArticlePreviousAndNextDataDto>>.Success(returnDto));
                }
                else
                    return OpenResponse.Ok(WebPortalDeResponse<List<ArticlePreviousAndNextDataDto>>.Success(null));
            }
        }

        /// <summary>
        /// 全文检索
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getfulltextsearchlist")]
        public async Task<OpenResponse> GetFullTextSearchList([FromBody] QueryArticleListDto dto)
        {
            if (string.IsNullOrEmpty(dto.PushRanges))
                dto.PushRanges = "2";

            if (string.IsNullOrEmpty(dto.Condition))
                return OpenResponse.Ok(WebPortalDeResponse<FullTextSearchListDataDto>.Success(null));

            RefAsync<int> total = 0;
            var items = await _bulletinRepository.Queryable()
                .Where(p => p.LoseEfficacyTime >= DateTime.Now)
                 .Where(p => p.IsArrive == true)
                .Where(p => SqlFunc.JsonListObjectAny(p.PushRanges, "Key", dto.PushRanges))
                .WhereIF(_appOptions.Value.IsYiBin, p => p.BulletinTypeId == "1" || p.BulletinTypeId == "5" || p.BulletinTypeId == "6" || p.BulletinTypeId == "7" || p.BulletinTypeId == "3" || p.BulletinTypeId == "4")
                .WhereIF(_appOptions.Value.IsZiGong, p => p.BulletinTypeId == "5013" || p.BulletinTypeId == "5016" || p.BulletinTypeId == "5011" || p.BulletinTypeId == "5015" || p.BulletinTypeId == "5017")
                .WhereIF(!string.IsNullOrEmpty(dto.Condition), p => p.Title.Contains(dto.Condition))
                 .OrderByDescending(p => p.CreationTime)
                 .Select(it => new
                 {
                     Page = SqlFunc.RowNumber($"{it.CreationTime} desc "),
                     NoticeID = it.Id,
                     Content = it.Content,
                     NoticeTypeID = it.BulletinTypeId,
                     NoticeTypeName = it.BulletinTypeName,
                     NoticeTitle = it.Title,
                     NoticeBMName = it.SourceOrgName,
                     NoticeCreateDate = it.CreationTime,
                     TypeCode = "",
                 })
                .ToPageListAsync(dto.PageIndex, dto.PageSize, total);

            //计算总页数
            int nPageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(total) / dto.PageSize));
            FullTextSearchListDataDto dataDto = new()
            {
                PageCount = nPageCount,
                data = _mapper.Map<IReadOnlyList<FullTextSearchListDto>>(items)
            };
            return OpenResponse.Ok(WebPortalDeResponse<FullTextSearchListDataDto>.Success(dataDto));
        }

        #endregion

        #region 用户
        /// <summary>
        /// 添加统一认证用户数据
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("adduserauth")]
        public async Task<OpenResponse> AddUserAuth([FromBody] UserModelDto dto)
        {
            bool bResult = false;
            // 唯一记录ID
            string id = dto.id;
            // 注册用户ID      
            string webUserID = "";
            // 统一认证用户注册ID
            string wUAID = "";
            //查询是否有注册用户
            var dataUser = await _webUserAuthRepository.GetAsync(p => p.DataId == id, HttpContext.RequestAborted);
            if (dataUser != null)
            {
                webUserID = dataUser.WebUserID;
                wUAID = dataUser.Id;
            }
            //没有注册用户添加数据
            if (string.IsNullOrEmpty(webUserID))
            {
                var userRegister = _mapper.Map<WebUserRegister>(dto);
                userRegister.RegDate = DateTime.Now;
                userRegister.LastDate = DateTime.Now;
                webUserID = await _webUserRegisterRepository.AddAsync(userRegister, HttpContext.RequestAborted);
            }

            //统一认证数据
            var userAuth = _mapper.Map<WebUserAuth>(dto);
            if (!string.IsNullOrEmpty(wUAID))
            {
                //修改数据
                userAuth.Id = wUAID;
                await _webUserAuthRepository.UpdateAsync(userAuth, HttpContext.RequestAborted);
                bResult = true;
            }
            else
            {
                //新增数据
                userAuth.WebGUID = Guid.NewGuid().ToString();
                userAuth.WebUserID = webUserID;
                var addId = await _webUserAuthRepository.AddAsync(userAuth, HttpContext.RequestAborted);
                if (!string.IsNullOrEmpty(addId))
                    bResult = true;
            }
            //判断是否成功
            if (bResult)
                return OpenResponse.Ok(WebPortalDeResponse<string>.Success(webUserID));
            else
                return OpenResponse.Ok(WebPortalDeResponse<string>.Failed());
        }

        /// <summary>
        /// 用户中心用户写信数据
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("getorderbyuserlist")]
        [AllowAnonymous]
        public async Task<OpenResponse> GetOrderByUserList([FromBody] QueryOrderListByUserDto dto)
        {
            var dataUser = await _webUserAuthRepository.GetAsync(p => p.DataId == dto.UserId, HttpContext.RequestAborted);
            if (dataUser != null)
            {
                RefAsync<int> total = 0;
                var items = await _webFlowAcceptRepository.Queryable()
                   .LeftJoin<Hotline.Orders.Order>((o, or) => o.OrderId == or.Id)
                   .Where(o => o.WebUserID == dataUser.WebUserID)
               //重新构建数据
               .Select((o, or) => new
               {
                   FlowID = o.OrderId,
                   FlowCode = o.Code,
                   FlowPwd = o.Pwd,
                   FlowTitle = o.Title,
                   FlowFromName = or.SourceChannel,
                   FlowPurTypeName = o.PurTypeName,
                   ConTypeName = or.HotspotName,
                   FlowAddDate = o.CreationTime,
                   RSFlagName = or.Status < EOrderStatus.Filed ? "办理中" : "办理完成",
                   WebUserID = o.WebUserID
               })
           //将结果合并成一个表
           .MergeTable()
                  .Where(p => p.WebUserID == dataUser.WebUserID)
               .ToPageListAsync(dto.PageIndex, dto.PageSize, total);

                //计算总页数
                int nPageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(total) / dto.PageSize));
                OrderListReturnDto returnDto = new()
                {
                    PageNum = dto.PageIndex,
                    PageCount = nPageCount,
                    Data = _mapper.Map<IReadOnlyList<OrderListDto>>(items)
                };

                return OpenResponse.Ok(WebPortalDeResponse<OrderListReturnDto>.Success(returnDto, "成功"));
            }
            return OpenResponse.Ok(WebPortalDeResponse<OrderListReturnDto>.Success(new OrderListReturnDto(), "成功"));

        }

        /// <summary>
        /// 用户中心用户写信数据
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("getorderbyuserphonelist")]
        [AllowAnonymous]
        public async Task<OpenResponse> GetOrderByUserPhoneList([FromBody] QueryOrderListByUserDto dto)
        {
            RefAsync<int> total = 0;
            var items = await _webFlowAcceptRepository.Queryable()
               .LeftJoin<Hotline.Orders.Order>((o, or) => o.OrderId == or.Id)
               .Where(o => o.Mobile == dto.PhoneNum)
           //重新构建数据
           .Select((o, or) => new
           {
               FlowID = o.OrderId,
               FlowCode = o.Code,
               FlowPwd = o.Pwd,
               FlowTitle = o.Title,
               FlowFromName = or.SourceChannel,
               FlowPurTypeName = o.PurTypeName,
               ConTypeName = or.HotspotName,
               FlowAddDate = o.CreationTime,
               RSFlagName = or.Status < EOrderStatus.Filed ? "办理中" : "办理完成",
               Mobile = o.Mobile
           })
           //将结果合并成一个表
           .MergeTable()
           .Where(p => p.Mobile == dto.PhoneNum)
           .ToPageListAsync(dto.PageIndex, dto.PageSize, total);

            //计算总页数
            int nPageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(total) / dto.PageSize));
            OrderListReturnDto returnDto = new()
            {
                PageNum = dto.PageIndex,
                PageCount = nPageCount,
                Data = _mapper.Map<IReadOnlyList<OrderListDto>>(items)
            };

            return OpenResponse.Ok(WebPortalDeResponse<OrderListReturnDto>.Success(returnDto, "成功"));

        }
        #endregion

        #region 短信、基础设置
        /// <summary>
        /// 短信验证码发送
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("writeletterssendsms")]
        public async Task<OpenResponse> WriteLettersSendSms([FromBody] WebPortalSendSmsModelDto dto)
        {
            string keyToken = "SmsUserWriteKey_" + dto.TelNum + "_" + DateTime.Now.ToString("yyyyMMdd");

            var data = await _writeLettersSendSms.GetAsync(keyToken, HttpContext.RequestAborted);
            if (data != null)//已经发过短信
            {
                //是否可以继续发送短信(10次)
                if (data.SendCount > 10)
                    //短信发送超过10条
                    return OpenResponse.Ok(WebPortalDeResponse<string>.Success("-2"));

                // 验证是否在两分钟之内
                TimeSpan duration = DateTime.Now - data.AddTime; // 计算时间差
                if ((int)duration.TotalSeconds < 120)
                    // 距离上次发送时间不足两分钟
                    return OpenResponse.Ok(WebPortalDeResponse<string>.Success("-4"));

                //修改缓存信息
                data.SendCount++;
                data.SmsCode = dto.SmsCode;
                data.AddTime = DateTime.Now;

            }
            else
            {
                //没有发过短信，直接写入数据
                data = new WriteLettersSendSmsDto
                {
                    AddTime = DateTime.Now,
                    SmsCode = dto.SmsCode,
                    MobileNum = dto.TelNum,
                    SendCount = 1
                };
            }
            //这里发送短信  宜宾12345市民服务热线网站验证码{0}，用于写信时验证联系电话。验证码有效期10分钟。

            var messageDto = new Share.Dtos.Push.MessageDto
            {
                PushBusiness = EPushBusiness.MsgCode,
                ExternalId = "",
                OrderId = "",
                PushPlatform = EPushPlatform.Web,
                Remark = "",
                Name = dto.TelNum,
                TemplateCode = "1008",
                Params = new List<string>() { dto.SmsCode },
                TelNumber = dto.TelNum,

            };
            await _mediator.Publish(new PushMessageNotify(messageDto), HttpContext.RequestAborted);

            //修改缓存
            await _writeLettersSendSms.SetAsync(keyToken, data, TimeSpan.FromDays(1), HttpContext.RequestAborted);

            return OpenResponse.Ok(WebPortalDeResponse<string>.Success("1"));
        }

        /// <summary>
        /// 验证短信验证码是否正确   正确返回1，错误返回-1
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("checksmscode")]
        public async Task<OpenResponse> CheckSmsCode([FromBody] WebPortalSendSmsModelDto dto)
        {
            string keyToken = "SmsUserWriteKey_" + dto.TelNum + "_" + DateTime.Now.ToString("yyyyMMdd");

            var data = await _writeLettersSendSms.GetAsync(keyToken, HttpContext.RequestAborted);
            //检测是否存在
            if (data != null)
                return OpenResponse.Ok(WebPortalDeResponse<string>.Success(data.SmsCode));

            //不存在
            return OpenResponse.Ok(WebPortalDeResponse<string>.Success("-1"));
        }

        /// <summary>
        /// 获取热点分类的树形
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("gethotspottreelist")]
        public async Task<OpenResponse> GetHotspotTreeList()
        {
            var data = await _hotspotRepository.Queryable().ToTreeAsync(it => it.Children, it => it.ParentId, null);
            return OpenResponse.Ok(WebPortalDeResponse<List<Hotspot>>.Success(data));
        }

        /// <summary>
        /// 系统主题颜色
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getsystemsettingstheme")]
        public async Task<OpenResponse> GetSystemSettingsTheme()
        {
            var WebSystemSettingsTheme = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.WebSystemSettingsTheme).SettingValue[0]);

            if (WebSystemSettingsTheme == false)
                return OpenResponse.Ok(WebPortalDeResponse<string>.Success(""));

            else
                return OpenResponse.Ok(WebPortalDeResponse<string>.Success("class=gray2"));

        }
        #endregion

        #region 办件
        /// <summary>
        /// 获取信件前6条数据
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("getorderlistbynum")]
        [AllowAnonymous]
        public async Task<OpenResponse> GetOrderListByNum([FromBody] QueryOrderListByNumDto dto)
        {
            var queryNew = _orderRepository.Queryable()
                .LeftJoin<OrderPublish>((p, op) => p.Id == op.OrderId)
                .Where(p => p.IsPublicity == true)
                .OrderByDescending((p, op) => p.CreationTime)
               .Select((p, op) => new DataListTopDto
               {
                   DataID = p.Id,
                   Title = p.Title,
                   CreateDate = op.CreationTime
               });

            var queryold = _oldPublicDataRepository.Queryable()
                      .OrderByDescending(p => p.PubDate)
                       .Select(p => new DataListTopDto
                       {
                           DataID = p.OrderId,
                           Title = p.Title,
                           CreateDate = p.CreationTime
                       });
            var items = await _orderRepository.UnionAll(queryNew, queryold)
              .OrderByDescending(p => p.CreateDate)
               .Take(dto.Num)
                .ToListAsync();
            var data = _mapper.Map<IReadOnlyList<DataListTopDto>>(items);
            return OpenResponse.Ok(WebPortalDeResponse<IReadOnlyList<DataListTopDto>>.Success(data, "成功"));
        }

        /// <summary>
        /// 办件摘编列表数据
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("getorderlist")]
        [AllowAnonymous]
        public async Task<OpenResponse> GetOrderList([FromBody] QueryOrderListDto dto)
        {
            RefAsync<int> total = 0;

            var queryNew = _orderPublishRepository.Queryable()
                 .Includes(d => d.Order)
                .Where(d => d.PublishState == true && d.Order.Id != null)
                .WhereIF(!string.IsNullOrEmpty(dto.FlowCode), d => d.Order.No == dto.FlowCode)
                .WhereIF(!string.IsNullOrEmpty(dto.FlowName), d => d.Order.Title.Contains(dto.FlowName))
                .WhereIF(!string.IsNullOrEmpty(dto.FlowSType), d => d.Order.AcceptTypeCode == dto.FlowSType)
                .WhereIF(!string.IsNullOrEmpty(dto.FlowRType), d => d.Order.HotspotId == dto.FlowRType)
                .WhereIF(!string.IsNullOrEmpty(dto.FlowSDate), d => d.Order.StartTime >= DateTime.Parse(DateTime.Parse(dto.FlowSDate).ToString("yyyy-MM-dd 00:00:00")))//dto.FlowSDate
                .WhereIF(!string.IsNullOrEmpty(dto.FlowEDate), d => d.Order.StartTime <= DateTime.Parse(DateTime.Parse(dto.FlowEDate).ToString("yyyy-MM-dd 00:00:00")))// dto.FlowEDate
                .WhereIF(!string.IsNullOrEmpty(dto.FlowFrom), d => d.Order.FromName.Contains(dto.FlowFrom))
                .OrderByDescending(p => p.CreationTime)
               .Select(p => new OrderListDto
               {
                   FlowID = p.OrderId,
                   FlowCode = p.No,
                   FlowPwd = p.Order.Password,
                   FlowTitle = p.Order.Title,
                   FlowFromName = p.Order.SourceChannel,
                   FlowPurTypeName = p.Order.AcceptType,
                   ConTypeName = p.Order.HotspotName,
                   FlowAddDate = p.Order.CreationTime,
                   RSFlagName = p.Order.Status >= EOrderStatus.Filed ? "办理完成" : "办理中",
                   PubDate = p.CreationTime
               });

            var queryold = _oldPublicDataRepository.Queryable()
                       .WhereIF(!string.IsNullOrEmpty(dto.FlowCode), d => d.OrderNo == dto.FlowCode)
                .WhereIF(!string.IsNullOrEmpty(dto.FlowName), d => d.Title.Contains(dto.FlowName))
                .WhereIF(!string.IsNullOrEmpty(dto.FlowSType), d => d.AcceptTypeCode == dto.FlowSType)
                .WhereIF(!string.IsNullOrEmpty(dto.FlowSDate), d => d.PubDate >= DateTime.Parse(DateTime.Parse(dto.FlowSDate).ToString("yyyy-MM-dd 00:00:00")))//dto.FlowSDate
                .WhereIF(!string.IsNullOrEmpty(dto.FlowEDate), d => d.PubDate <= DateTime.Parse(DateTime.Parse(dto.FlowEDate).ToString("yyyy-MM-dd 00:00:00")))// dto.FlowEDate
                .WhereIF(!string.IsNullOrEmpty(dto.FlowFrom), d => d.FromName.Contains(dto.FlowFrom))
                      .OrderByDescending(p => p.PubDate)
                       .Select(p => new OrderListDto
                       {
                           FlowID = p.OrderId,
                           FlowCode = p.OrderNo,
                           FlowPwd = p.OrderPwd,
                           FlowTitle = p.Title,
                           FlowFromName = p.SourceChannel,
                           FlowPurTypeName = p.AcceptType,
                           ConTypeName = p.HotspotName,
                           FlowAddDate = p.AcceptTime,
                           RSFlagName = p.State == "1" ? "办理完成" : "办理中",
                           PubDate = p.CreationTime
                       });

            var items = await _orderRepository.UnionAll(queryNew, queryold)
            .OrderByDescending(p => p.PubDate)
              .ToPageListAsync(dto.PageIndex, dto.PageSize, total);

            //计算总页数
            int nPageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(total) / dto.PageSize));
            OrderListReturnDto returnDto = new()
            {
                PageNum = dto.PageIndex,
                PageCount = nPageCount,
                Data = _mapper.Map<IReadOnlyList<OrderListDto>>(items)
            };

            return OpenResponse.Ok(WebPortalDeResponse<OrderListReturnDto>.Success(returnDto, "成功"));
        }

        /// <summary>
        /// 查询工单发布后公开的数据
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("get_order_list_publish_all")]
        [AllowAnonymous]
        public async Task<OpenResponse> GetOrderByListAllOpen([FromBody] QueryOrderListDto dto)
        {
            var queryNew = _orderPublishRepository.Queryable()
                .LeftJoin<Order>((op, p) => p.Id == op.OrderId)
                .Where((op, p) => op.PublishState == true)
                .WhereIF(!string.IsNullOrEmpty(dto.FlowCode), (op, p) => p.No == dto.FlowCode)
                .WhereIF(!string.IsNullOrEmpty(dto.FlowName), (op, p) => op.ArrangeTitle.Contains(dto.FlowName))
                .WhereIF(!string.IsNullOrEmpty(dto.FlowSType), (op, p) => p.AcceptTypeCode == dto.FlowSType)
                .WhereIF(!string.IsNullOrEmpty(dto.FlowRType), (op, p) => p.HotspotId == dto.FlowRType)
                .WhereIF(!string.IsNullOrEmpty(dto.FlowSDate), (op, p) => p.StartTime >= DateTime.Parse(DateTime.Parse(dto.FlowSDate).ToString("yyyy-MM-dd 00:00:00")))//dto.FlowSDate
                .WhereIF(!string.IsNullOrEmpty(dto.FlowEDate), (op, p) => p.StartTime <= DateTime.Parse(DateTime.Parse(dto.FlowEDate).ToString("yyyy-MM-dd 00:00:00")))// dto.FlowEDate
                .WhereIF(!string.IsNullOrEmpty(dto.FlowFrom), (op, p) => p.FromName.Contains(dto.FlowFrom))
                .WhereIF(dto.IdentityType.HasValue, (op, p) => p.IdentityType == dto.IdentityType)
                .OrderByDescending((op, p) => p.CreationTime)
               .Select((op, p) => new OrderListDto
               {
                   FlowID = p.Id,
                   FlowCode = p.No,
                   FlowPwd = p.Password,
                   FlowTitle = op.ArrangeTitle,
                   FlowFromName = p.SourceChannel,
                   FlowPurTypeName = p.AcceptType,
                   ConTypeName = p.HotspotName,
                   FlowAddDate = p.CreationTime,
                   PubDate = op.CreationTime,
                   RSFlagName = p.Status >= EOrderStatus.Filed ? "办理完成" : "办理中"
               });

            //if (_appOptions.Value.IsLuZhou)
            //{
            //    // 添加只查询临时待发布的公开件
            //    queryNew = queryNew.Where(it => SqlFunc.Subqueryable<OrderPublishTemp>().Where(s => s.Id == it.FlowID).Any());
            //}

            var queryold = _oldPublicDataRepository.Queryable()
                      .WhereIF(!string.IsNullOrEmpty(dto.FlowCode), p => p.OrderNo == dto.FlowCode)
                      .WhereIF(!string.IsNullOrEmpty(dto.FlowName), p => p.Title.Contains(dto.FlowName))
                      .WhereIF(!string.IsNullOrEmpty(dto.FlowSType), p => p.AcceptTypeCode == dto.FlowSType)
                      .WhereIF(!string.IsNullOrEmpty(dto.FlowRType), p => p.HotspotId == dto.FlowRType)
                      .WhereIF(!string.IsNullOrEmpty(dto.FlowSDate), p => p.AcceptTime >= DateTime.Parse(DateTime.Parse(dto.FlowSDate).ToString("yyyy-MM-dd 00:00:00")))//dto.FlowSDate
                      .WhereIF(!string.IsNullOrEmpty(dto.FlowEDate), p => p.AcceptTime <= DateTime.Parse(DateTime.Parse(dto.FlowEDate).ToString("yyyy-MM-dd 00:00:00")))// dto.FlowEDate
                      .WhereIF(!string.IsNullOrEmpty(dto.FlowFrom), p => p.FromName.Contains(dto.FlowFrom))
                      .WhereIF(dto.IdentityType.HasValue, p => p.IdentityType == dto.IdentityType)
                      .OrderByDescending(p => p.PubDate)
                        .Select(p => new OrderListDto
                        {
                            FlowID = p.OrderId,
                            FlowCode = p.OrderNo,
                            FlowPwd = p.OrderPwd,
                            FlowTitle = p.Title,
                            FlowFromName = p.SourceChannelCode,
                            FlowPurTypeName = p.AcceptTypeCode,
                            ConTypeName = p.HotspotName,
                            FlowAddDate = p.CreationTime,
                            PubDate = p.CreationTime,
                            RSFlagName = p.State == "1" ? "办理完成" : "办理中"
                        });

            var (total, items) = await _orderRepository.UnionAll(queryNew, queryold)
                .OrderByDescending(p => p.PubDate)
                 .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);

            //计算总页数
            int nPageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(total) / dto.PageSize));
            OrderListReturnDto returnDto = new()
            {
                Total = total,
                PageNum = dto.PageIndex,
                PageCount = nPageCount,
                Data = _mapper.Map<IReadOnlyList<OrderListDto>>(items)
            };

            return OpenResponse.Ok(WebPortalDeResponse<OrderListReturnDto>.Success(returnDto, "成功"));
        }

        /// <summary>
        /// 查询工单发布后公开的数据
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("get_order_list_all_bynoortitle")]
        [AllowAnonymous]
        public async Task<OpenResponse> GetOrderByListAllByNoOrTitle([FromBody] QueryOrderListDto dto)
        {
            var (total, items) = await _orderPublishRepository.Queryable()
                .LeftJoin<Order>((op, p) => p.Id == op.OrderId)
                .WhereIF(!string.IsNullOrEmpty(dto.FlowCode), (op, p) => p.No == dto.FlowCode)
                .WhereIF(!string.IsNullOrEmpty(dto.FlowName), (op, p) => op.ArrangeTitle.Contains(dto.FlowName))
                .WhereIF(!string.IsNullOrEmpty(dto.FlowSType), (op, p) => p.AcceptTypeCode == dto.FlowSType)
                .WhereIF(!string.IsNullOrEmpty(dto.FlowRType), (op, p) => p.HotspotId == dto.FlowRType)
                .WhereIF(!string.IsNullOrEmpty(dto.FlowSDate), (op, p) => p.StartTime >= DateTime.Parse(DateTime.Parse(dto.FlowSDate).ToString("yyyy-MM-dd 00:00:00")))//dto.FlowSDate
                .WhereIF(!string.IsNullOrEmpty(dto.FlowEDate), (op, p) => p.StartTime <= DateTime.Parse(DateTime.Parse(dto.FlowEDate).ToString("yyyy-MM-dd 00:00:00")))// dto.FlowEDate
                .WhereIF(!string.IsNullOrEmpty(dto.FlowFrom), (op, p) => p.FromName.Contains(dto.FlowFrom))
                .WhereIF(dto.IdentityType.HasValue, (op, p) => p.IdentityType == dto.IdentityType)
                .OrderByDescending((op, p) => p.CreationTime)
               .Select((op, p) => new OrderListDto
               {
                   FlowID = p.Id,
                   FlowCode = p.No,
                   FlowPwd = p.Password,
                   FlowTitle = op.ArrangeTitle,
                   FlowFromName = p.SourceChannel,
                   FlowPurTypeName = p.AcceptType,
                   ConTypeName = p.HotspotName,
                   FlowAddDate = p.CreationTime,
                   PubDate = op.CreationTime,
                   RSFlagName = p.Status >= EOrderStatus.Filed ? "办理完成" : "办理中"
               })
               .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);

            OrderListReturnAllDto returnDto = new()
            {
                Total = total,
                Data = _mapper.Map<IReadOnlyList<OrderListDto>>(items)
            };

            return OpenResponse.Ok(WebPortalDeResponse<OrderListReturnAllDto>.Success(returnDto, "成功"));
        }

        /// <summary>
        /// 办件摘编详情
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getorderdetailbyid")]
        public async Task<OpenResponse> GetOrderDetailById([FromBody] ArticleIdDto dto)
        {
            var data = await _orderRepository.GetAsync(p => p.Id == dto.Id, HttpContext.RequestAborted);
            var orderDetail = _mapper.Map<OrderDetail>(data);
            if (_appOptions.Value.IsZiGong)
            {
                orderDetail.FlowResult = "";
            }

            if (data != null)
            {
                //如果是省工单或者是省政民互动的工单，市民不能进行评价
                if (data.IsProvince == true || data.SourceChannelCode == "ZMHD")
                    orderDetail.IsProvinceOrder = "1";
                else
                    orderDetail.IsProvinceOrder = "0";

                //获取发布的数据
                var orderPublish = await _orderPublishRepository.GetAsync(p => p.OrderId == data.Id, HttpContext.RequestAborted);
                if (orderPublish != null)
                {
                    orderDetail.PubFlag = "1";
                    orderDetail.FlowTitle = orderPublish.ArrangeTitle;
                    orderDetail.FlowContent = orderPublish.ArrangeContent;

                    if (_appOptions.Value.IsZiGong)
                    {
                        if (data.Source == ESource.ProvinceStraight)
                            orderDetail.FlowResult = orderPublish.ArrangeOpinion;
                        if (data.Source != ESource.ProvinceStraight && data.Status >= EOrderStatus.Visited)
                            orderDetail.FlowResult = orderPublish.ArrangeOpinion;
                    }
                    else
                        orderDetail.FlowResult = orderPublish.ArrangeOpinion;

                    if (orderPublish.PublishState)
                        orderDetail.FlowPubFlagName = "公开";
                }

                //能否进行评价
                var orderVisit = await _orderVisitRepository.GetAsync(p => p.OrderId == data.Id && p.VisitState != EVisitState.None, HttpContext.RequestAborted);
                if (orderVisit == null)
                    orderDetail.VisitType = "0";
                else
                {
                    orderDetail.VisitType = orderVisit.VisitState switch
                    {
                        EVisitState.WaitForVisit => "1",
                        EVisitState.Visited => "2",
                        EVisitState.Visiting or EVisitState.NoSatisfiedWaitForVisit or EVisitState.None => "0",
                        _ => "0",
                    };
                }

            }
            List<OrderDetail> dataDto = new() { orderDetail };
            return OpenResponse.Ok(WebPortalDeResponse<IReadOnlyList<OrderDetail>>.Success(dataDto));
        }

        /// <summary>
        /// 根据编号和密码查询信件ID
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getorderid")]
        public async Task<OpenResponse> GetOrderId([FromBody] GetOrderCodePwd dto)
        {
            var data = await _orderRepository.GetAsync(p => p.No == dto.OrderNo && p.Password == dto.Pwd, HttpContext.RequestAborted);//&& p.Status > EOrderStatus.Published
            return OpenResponse.Ok(WebPortalDeResponse<string>.Success(data?.Id));
        }

        /// <summary>
        /// 办件摘编详情
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getorderdetailbyno")]
        public async Task<OpenResponse> GetOrderDetailByNo([FromBody] GetOrderCodePwd dto)
        {
            var data = await _orderRepository.GetAsync(p => p.No == dto.OrderNo && p.Password == dto.Pwd, HttpContext.RequestAborted);
            if (data != null)
            {
                var orderDetail = _mapper.Map<OrderDetail>(data);
                if (data != null)
                {
                    //如果是省工单或者是省政民互动的工单，市民不能进行评价
                    if (data.IsProvince == true || data.SourceChannelCode == "ZMHD")
                        orderDetail.IsProvinceOrder = "1";
                    else
                        orderDetail.IsProvinceOrder = "0";

                    //获取发布的数据
                    var orderPublish = await _orderPublishRepository.GetAsync(p => p.OrderId == data.Id, HttpContext.RequestAborted);
                    if (orderPublish != null)
                    {
                        orderDetail.PubFlag = "1";
                        orderDetail.FlowTitle = orderPublish.ArrangeTitle;
                        orderDetail.FlowContent = orderPublish.ArrangeContent;
                        orderDetail.FlowResult = orderPublish.ArrangeOpinion;
                        if (orderPublish.PublishState)
                            orderDetail.FlowPubFlagName = "公开";
                    }

                    //能否进行评价
                    var orderVisit = await _orderVisitRepository.GetAsync(p => p.OrderId == data.Id && p.VisitState != EVisitState.None, HttpContext.RequestAborted);
                    if (orderVisit == null)
                        orderDetail.VisitType = "0";
                    else
                    {
                        orderDetail.VisitType = orderVisit.VisitState switch
                        {
                            EVisitState.WaitForVisit => "1",
                            EVisitState.Visited => "2",
                            EVisitState.Visiting or EVisitState.NoSatisfiedWaitForVisit or EVisitState.None => "0",
                            _ => "0",
                        };
                    }

                }
                List<OrderDetail> dataDto = new() { orderDetail };
                return OpenResponse.Ok(WebPortalDeResponse<IReadOnlyList<OrderDetail>>.Success(dataDto));
            }
            return OpenResponse.Ok(WebPortalDeResponse<IReadOnlyList<string>>.Failed(code: "0", description: "查询失败"));
        }

        /// <summary>
        /// 写信接口
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("orderacceptance")]
        public async Task<OpenResponse> OrderAcceptance([FromBody] WebFlowAcceptDto dto)
        {
            //电话号码去空格
            if (!string.IsNullOrEmpty(dto.Mobile))
                dto.Mobile = dto.Mobile.Trim();

            var data = _mapper.Map<Hotline.Share.Dtos.Order.AddOrderDto>(dto);
            data.Source = ESource.WebPortal;
            data.SourceChannel = "因特网";
            data.SourceChannelCode = "YTW";

            switch (dto.FromID)
            {
                case "2":
                    data.SourceChannel = "APP";
                    data.SourceChannelCode = "AP";
                    data.Source = ESource.APP;
                    break;
                case "3":
                    data.SourceChannel = "微信小程序";
                    data.SourceChannelCode = "XCX";
                    data.Source = ESource.WeChat;
                    break;
                case "9"://宜宾人社专用
                    data.SourceChannel = "人社APP";
                    data.SourceChannelCode = "RSAPP";
                    data.Source = ESource.YBHumanSocietyAPP;
                    break;
                default:
                    break;
            }
            if (!string.IsNullOrEmpty(data.LicenceNo))
            {
                data.LicenceTypeCode = "10";
                data.LicenceType = "中华人民共和国居民身份证";
            }
            data.ExternalId = Guid.NewGuid().ToString();

            data.IdentityType = dto.IdentityType;
            data.Transpond = false;
            data.IsEnforcementOrder = false;


            var result = await _orderApplication.ReceiveOrderFromExternalAsync(data, HttpContext.RequestAborted);

            OrderAcceptanceReturnDto returnDto = new();
            if (result != null)
            {
                returnDto.PWD = result.Password;
                returnDto.Code = result.No;
                returnDto.State = "1";

                dto.Pwd = result.Password;
                dto.Code = result.No;
                dto.OrderId = result.Id;
                var dtoData = _mapper.Map<WebFlowAccept>(dto);
                await _webFlowAcceptRepository.AddAsync(dtoData, HttpContext.RequestAborted);

            }
            else
                returnDto.State = "0";


            return OpenResponse.Ok(WebPortalDeResponse<OrderAcceptanceReturnDto>.Success(returnDto));
        }

        /// <summary>
        /// 受理类型和热点统计
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getchartdata")]
        public async Task<OpenResponse> GetChartData()
        {
            var startDate = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 00:00:00"));
            var endDate = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 23:59:59"));

            //数据查询
            var listType = await _orderRepository.Queryable()
                .Where(p => p.CreationTime >= startDate && p.CreationTime <= endDate && p.Status > EOrderStatus.WaitForAccept)
                .Select(it => new
                {
                    it.AcceptType,
                    it.AcceptTypeCode
                })
                .MergeTable()//将查询出来的结果合并成一个新表
                 .GroupBy(it => new { it.AcceptType, it.AcceptTypeCode })//对新表进行分组
                 .Select(it => new
                 {
                     name = it.AcceptType,
                     value = SqlFunc.AggregateCount(it.AcceptTypeCode)
                 })
                 .ToListAsync();

            var listHot = await _orderRepository.Queryable()
                .Where(it => it.CreationTime >= startDate && it.CreationTime <= endDate && it.Status > EOrderStatus.WaitForAccept)
                 .Select(it => new
                 {
                     HotspotId = it.HotspotId.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("2")),
                 })
                 .MergeTable()
                 .Where(it => it.HotspotId != "18")
                 .GroupBy(it => it.HotspotId)//对新表进行分组
                 .Select(it => new
                 {
                     HotspotId = it.HotspotId,
                     num = SqlFunc.AggregateCount(it.HotspotId)
                 })
                  .OrderByDescending(it => it.num)
                 .Take(5)
                 .MergeTable()
                 .LeftJoin<Hotspot>((it, h) => it.HotspotId == h.Id)
                 .Select((it, h) => new
                 {
                     typeName = h.HotSpotName,
                     num = it.num
                 }).ToListAsync();

            ////数据查询-查询总数前5的数据
            //var listHot = await _orderRepository.Queryable()
            //    .Where(p => p.StartTime >= startDate && p.StartTime <= endDate && p.Status > EOrderStatus.WaitForAccept)
            //    .Select(it => new
            //    {
            //        it.HotspotId,
            //        it.HotspotName
            //    })
            //    .MergeTable()//将查询出来的结果合并成一个新表
            //     .GroupBy(it => new { it.HotspotId, it.HotspotName })//对新表进行分组
            //     .Select(it => new
            //     {
            //         typeName = it.HotspotName,
            //         num = SqlFunc.AggregateCount(it.HotspotId)
            //     })
            //     .OrderByDescending(it => it.num)
            //     .Take(5)
            //     .ToListAsync();

            GetChartDataDto dataDto = new()
            {
                formCount = _mapper.Map<IReadOnlyList<OrderFormCount>>(listType),
                hotCount = _mapper.Map<IReadOnlyList<OrderHotCount>>(listHot)
            };

            return OpenResponse.Ok(WebPortalDeResponse<GetChartDataDto>.Success(dataDto));
        }

        /// <summary>
        /// 获取统计数据
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getstatist")]
        public async Task<OpenResponse> GetStatist()
        {
            var startDate = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 00:00:00"));
            var endDate = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 23:59:59"));
            //GetStatistDto getStatistDto = new()
            //{
            //    AllCount = await _orderRepository.Queryable().Where(p => p.Status > EOrderStatus.WaitForAccept).CountAsync(),
            //    AllTrandCount = await _orderRepository.Queryable().Where(p => p.Status >= EOrderStatus.Filed).CountAsync(),
            //    DayCount = await _orderRepository.Queryable().Where(p => p.StartTime >= startDate && p.StartTime <= endDate && p.Status > EOrderStatus.WaitForAccept).CountAsync(),
            //    DayTrandCount = await _orderRepository.Queryable().Where(p => p.ActualHandleTime >= startDate && p.ActualHandleTime <= endDate && p.Status >= EOrderStatus.Filed).CountAsync()
            //};
            var getStatistDto = await _orderRepository.Queryable()
          .Select(p => new GetStatistDto
          {
              AllCount = SqlFunc.AggregateSum(SqlFunc.IIF(p.Status > EOrderStatus.WaitForAccept, 1, 0)) + 7079457,
              AllTrandCount = SqlFunc.AggregateSum(SqlFunc.IIF(p.Status >= EOrderStatus.Filed, 1, 0)) + 7079214,
              DayCount = SqlFunc.AggregateSum(SqlFunc.IIF(p.CreationTime >= startDate && p.CreationTime <= endDate && p.Status > EOrderStatus.WaitForAccept, 1, 0)),
              DayTrandCount = SqlFunc.AggregateSum(SqlFunc.IIF(p.CreationTime >= startDate && p.CreationTime <= endDate && p.FiledTime >= startDate && p.FiledTime <= endDate && p.Status >= EOrderStatus.Filed, 1, 0)),
          })
          .FirstAsync();
            return OpenResponse.Ok(WebPortalDeResponse<GetStatistDto>.Success(getStatistDto));
        }

        /// <summary>
        /// 获取统计数据 今日数据
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("todaygetstatist")]
        public async Task<OpenResponse> GetTodayStatist()
        {
            var startDate = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 00:00:00"));
            var endDate = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 23:59:59"));
            var getStatistDto = await _orderRepository.Queryable()
          .Select(p => new GetStatistDto
          {
              DayCount = SqlFunc.AggregateSum(SqlFunc.IIF(p.CreationTime >= startDate && p.CreationTime <= endDate && p.Status > EOrderStatus.WaitForAccept, 1, 0)),
              DayTrandCount = SqlFunc.AggregateSum(SqlFunc.IIF(p.CreationTime >= startDate && p.CreationTime <= endDate && p.FiledTime >= startDate && p.FiledTime <= endDate && p.Status >= EOrderStatus.Filed, 1, 0)),
          })
          .FirstAsync();
            return OpenResponse.Ok(WebPortalDeResponse<GetStatistDto>.Success(getStatistDto));
        }
        #endregion

        #region 评价
        /// <summary>
        /// 获取待评价部门信息
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getwaitvisitdata")]
        public async Task<OpenResponse> GetWaitVisitData([FromBody] ArticleIdDto dto)
        {
            var dataOrder = await _orderVisitRepository.GetAsync(p => p.OrderId == dto.Id && p.VisitState != EVisitState.None, HttpContext.RequestAborted);
            if (dataOrder == null)
                return OpenResponse.Ok(WebPortalDeResponse<List<WaitVisitListDataDto>>.Failed("工单不能评价！"));

            if (dataOrder.VisitState != EVisitState.WaitForVisit)
                return OpenResponse.Ok(WebPortalDeResponse<List<WaitVisitListDataDto>>.Failed("工单已经评价！"));

            var data = await _orderVisitDetailRepository.Queryable()
                .Where(p => p.VisitId == dataOrder.Id && p.VisitTarget == EVisitTarget.Org)
                .ToListAsync();

            var listDat = _mapper.Map<List<WaitVisitListDataDto>>(data);
            return OpenResponse.Ok(WebPortalDeResponse<List<WaitVisitListDataDto>>.Success(listDat));
        }

        /// <summary>
        /// 评价内容
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("receivevisitdata")]
        public async Task<OpenResponse> ReceiveVisitData([FromBody] OrderVisitListDataDto dto)
        {
            if (dto == null || dto.VistListDtos == null || dto.VistListDtos.Count == 0)
                return OpenResponse.Ok(WebPortalDeResponse<string>.Failed("评价数据不能为空！"));

            var dataOrder = await _orderVisitRepository.GetAsync(p => p.OrderId == dto.OrderId && p.VisitState != EVisitState.None, HttpContext.RequestAborted);
            if (dataOrder == null)
                return OpenResponse.Ok(WebPortalDeResponse<string>.Failed("工单已经评价！"));

            //组装数据
            OrderVisitWebDto visitWebDto = new()
            {
                VisitType = Hotline.Share.Enums.Order.EVisitType.WebVisit,
                VisitTime = DateTime.Now
            };

            List<OrderVisitDetailWebDto> orderVisitDetails = new();

            #region 部门评价
            //部门评价
            //遍历数据
            foreach (var item in dto.VistListDtos)
            {
                Hotline.Share.Dtos.Kv kv = item.SatisfactionCode switch
                {
                    "5" => new Hotline.Share.Dtos.Kv { Key = "5", Value = "非常满意" },
                    "4" => new Hotline.Share.Dtos.Kv { Key = "4", Value = "满意" },
                    "2" => new Hotline.Share.Dtos.Kv { Key = "2", Value = "不满意" },
                    _ => new Hotline.Share.Dtos.Kv { Key = "7", Value = "不做评价" },
                };
                //组装回访数据
                visitWebDto.Id = item.VisitId;
                OrderVisitDetailWebDto detailDto = new()
                {
                    Id = item.Id,
                    VisitTarget = Hotline.Share.Enums.Order.EVisitTarget.Org,
                    OrgProcessingResults = kv,
                    OrgNoSatisfiedReason = new List<Hotline.Share.Dtos.Kv>(),
                    OrgHandledAttitude = kv,
                    VisitContent = item.VisitContent
                };
                orderVisitDetails.Add(detailDto);
            }
            #endregion

            visitWebDto.OrderVisitDetailDto = orderVisitDetails;

            //推送数据
            await _orderApplication.OrderVisitWeb(visitWebDto, HttpContext.RequestAborted);
            return OpenResponse.Ok(WebPortalDeResponse<string>.Success("1"));
        }
        #endregion

        #region 知识库

        /// <summary>
        /// 获取知识库分类
        /// </summary>
        /// <returns></returns>
        [HttpPost("getknowledgetype")]
        [AllowAnonymous]
        public async Task<OpenResponse> GetKnowledgeType()
        {
            //查询知识分类
            var item = await _knowledgeTypeRepository.Queryable()
                   .Where(p => p.ParentId == null || p.ParentId == "")
                   .Select(p => new
                   {
                       SDICT_ID = p.Id,
                       SDICT_Name = p.Name
                   })
                   .ToListAsync();

            //查询知识标签
            var list = _systemDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.KnowledgeBaseTags).Select(p => new
            {
                SDICT_Name = p.DicDataName,
                SDICT_ID = p.DicDataName
            }).ToList();

            var rsp = new
            {
                KnowledgeType = item,
                KnowledgeBaseTags = list,
            };
            return OpenResponse.Ok(WebPortalDeResponse<object>.Success(rsp));
        }

        /// <summary>
        /// 知识库查询
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("getknowledgelist")]
        [AllowAnonymous]
        public async Task<OpenResponse> GetKnowledgeList([FromBody] QueryKnowledgeList dto)
        {
            var typeSpliceName = string.Empty;
            if (!string.IsNullOrEmpty(dto.KnowledgeTypeId))
            {
                var type = await _knowledgeTypeRepository.GetAsync(x => x.Name == dto.KnowledgeTypeId);
                typeSpliceName = type?.SpliceName;
            }

            var typeSpliceNameTags = string.Empty;
            if (!string.IsNullOrEmpty(dto.KnowledgeBaseTags))
            {
                var type = await _knowledgeWordRepository.GetAsync(x => x.Tag == dto.KnowledgeBaseTags && x.IsEnable == 1);
                typeSpliceNameTags = type?.Id;
            }

            var (total, items) = await _knowledgeRepository.Queryable()
                .Where(p => p.IsPublic == true && p.Status == EKnowledgeStatus.OnShelf)
                .WhereIF(!string.IsNullOrEmpty(dto.Title), p => p.Title.Contains(dto.Title))
                .WhereIF(!string.IsNullOrEmpty(typeSpliceNameTags), p => SqlFunc.JsonArrayAny(p.Keywords, typeSpliceNameTags) == true)
                .WhereIF(!string.IsNullOrEmpty(typeSpliceName), x => x.KnowledgeType.Any(t => t.KnowledgeTypeSpliceName.EndsWith(typeSpliceName)))
                .OrderByDescending(p => p.CreationTime)
                .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);

            var data = new PagedDto<KnowledgeInfoDto>(total, _mapper.Map<IReadOnlyList<KnowledgeInfoDto>>(items));
            return OpenResponse.Ok(WebPortalDeResponse<PagedDto<KnowledgeInfoDto>>.Success(data));
        }

        /// <summary>
        /// 获取知识库详情
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("getknowledgeinfo")]
        [AllowAnonymous]
        public async Task<OpenResponse> GetKnowledgeInfo([FromBody] QueryKnowledgeInfo dto)
        {
            var data = await _knowledgeRepository.GetAsync(p => p.Id == dto.Id, HttpContext.RequestAborted);
            KnowledgeInfoDto detailsDto = null;
            if (data != null)
            {
                detailsDto = _mapper.Map<KnowledgeInfoDto>(data);

                if (detailsDto != null && !string.IsNullOrEmpty(detailsDto.Content))
                    data.Content = _bulletinApplication.GetSiteUrls(data.Content);
            }
            else
            {
                detailsDto = new();
            }
            List<KnowledgeInfoDto> dataDto = [detailsDto];
            return OpenResponse.Ok(WebPortalDeResponse<IReadOnlyList<KnowledgeInfoDto>>.Success(dataDto));
        }

        #endregion

        #region 查询受理类型

        /// <summary>
        /// 查询受理类型----受理量
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("getacceptancetypestatisticsbymonth")]
        [AllowAnonymous]
        public async Task<OpenResponse> GetAcceptanceTypeStatisticsByMonth([FromBody] OrderFormByMonthDto dto)
        {
            if (string.IsNullOrEmpty(dto.StartTime))
                dto.StartTime = DateTime.Now.ToString("yyyy-MM-dd 00:00:00");

            if (string.IsNullOrEmpty(dto.EndTime))
                dto.EndTime = DateTime.Now.ToString("yyyy-MM-dd 23:59:59");

            //查询待
            var listType = await _orderRepository.Queryable()
                .Where(p => p.CreationTime >= Convert.ToDateTime(dto.StartTime) && p.CreationTime <= Convert.ToDateTime(dto.EndTime) && p.Status > EOrderStatus.WaitForAccept)
                .Select(it => new
                {
                    it.AcceptType,
                    it.AcceptTypeCode
                })
                .MergeTable()//将查询出来的结果合并成一个新表
                 .GroupBy(it => new { it.AcceptType, it.AcceptTypeCode })//对新表进行分组
                 .Select(it => new
                 {
                     name = it.AcceptType,
                     value = SqlFunc.AggregateCount(it.AcceptTypeCode)
                 })
                 .ToListAsync();
            var formAcceptanceCount = _mapper.Map<List<OrderFormCount>>(listType);

            if (_appOptions.Value.IsZiGong)
            {
                List<OrderFormCount> orderForms = new List<OrderFormCount>();
                List<string> fromName = ["咨询", "投诉", "求助", "建议", "举报", "表扬", "申报"];
                foreach (var form in fromName)
                {
                    var data = formAcceptanceCount.FirstOrDefault(p => p.name == form);
                    orderForms.Add(new OrderFormCount()
                    {
                        name = form,
                        value = data == null ? 0 : data.value
                    });
                }
                return OpenResponse.Ok(WebPortalDeResponse<List<OrderFormCount>>.Success(orderForms));
            }


            return OpenResponse.Ok(WebPortalDeResponse<List<OrderFormCount>>.Success(formAcceptanceCount));
        }

        /// <summary>
        /// 查询受理类型---办结量
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("getacceptancetypestatisticsbymonthend")]
        [AllowAnonymous]
        public async Task<OpenResponse> GetAcceptanceTypeStatisticsByMonthEnd([FromBody] OrderFormByMonthDto dto)
        {
            if (string.IsNullOrEmpty(dto.StartTime))
                dto.StartTime = DateTime.Now.ToString("yyyy-MM-dd 00:00:00");

            if (string.IsNullOrEmpty(dto.EndTime))
                dto.EndTime = DateTime.Now.ToString("yyyy-MM-dd 23:59:59");

            //数据查询
            var listFileType = await _orderRepository.Queryable()
                .Where(p => p.FiledTime >= Convert.ToDateTime(dto.StartTime) && p.FiledTime <= Convert.ToDateTime(dto.EndTime) && p.Status >= EOrderStatus.Visited)
                .Select(it => new
                {
                    it.AcceptType,
                    it.AcceptTypeCode
                })
                .MergeTable()//将查询出来的结果合并成一个新表
                 .GroupBy(it => new { it.AcceptType, it.AcceptTypeCode })//对新表进行分组
                 .Select(it => new
                 {
                     name = it.AcceptType,
                     value = SqlFunc.AggregateCount(it.AcceptTypeCode)
                 })
                 .ToListAsync();

            var formFileCount = _mapper.Map<IReadOnlyList<OrderFormCount>>(listFileType);
            if (_appOptions.Value.IsZiGong)
            {
                List<OrderFormCount> orderForms = new List<OrderFormCount>();
                List<string> fromName = ["咨询", "投诉", "求助", "建议", "举报", "表扬", "申报"];
                foreach (var form in fromName)
                {
                    var data = formFileCount.FirstOrDefault(p => p.name == form);
                    orderForms.Add(new OrderFormCount()
                    {
                        name = form,
                        value = data == null ? 0 : data.value
                    });
                }
                return OpenResponse.Ok(WebPortalDeResponse<List<OrderFormCount>>.Success(orderForms));
            }
            return OpenResponse.Ok(WebPortalDeResponse<IReadOnlyList<OrderFormCount>>.Success(formFileCount));
        }

        #endregion

        #region 缓存值

        /// <summary>
        /// 缓存值
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("setgetvaildata")]
        [AllowAnonymous]
        public async Task<OpenResponse> SetGetVailData([FromBody] GetVailDataDto dto)
        {
            if (string.IsNullOrEmpty(dto.Key) || string.IsNullOrEmpty(dto.Value))
                return OpenResponse.Ok(WebPortalDeResponse<string>.Success("-1"));

            string strGuid = Guid.NewGuid().ToString();

            string keyToken = dto.Key + strGuid;
            await _getVailData.SetAsync(keyToken, dto.Value, TimeSpan.FromHours(1), cancellationToken: HttpContext.RequestAborted);
            return OpenResponse.Ok(WebPortalDeResponse<string>.Success(strGuid));
        }

        /// <summary>
        /// 缓存值
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("getgetvaildata")]
        [AllowAnonymous]
        public async Task<OpenResponse> GetGetVailData([FromBody] GetVailDataDto dto)
        {
            if (string.IsNullOrEmpty(dto.Key))
                return OpenResponse.Ok(WebPortalDeResponse<string>.Success("-1"));

            var data = await _getVailData.GetAsync(dto.Key, cancellationToken: HttpContext.RequestAborted);
            if (!string.IsNullOrEmpty(data) && data == dto.Value)
            {
                await _getVailData.RemoveAsync(dto.Key, cancellationToken: HttpContext.RequestAborted);
                return OpenResponse.Ok(WebPortalDeResponse<string>.Success("1"));
            }


            return OpenResponse.Ok(WebPortalDeResponse<string>.Success("-1"));
        }

        #endregion

        #region 通知-宜宾

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getarticlelist_yibin")]
        public async Task<OpenResponse> GetArticleListYiBin([FromBody] QueryArticleListDto dto)
        {
            if (string.IsNullOrEmpty(dto.PushRanges))
                dto.PushRanges = "2";

            RefAsync<int> total = 0;
            var items1 = _bulletinRepository.Queryable()
                .Where(p => p.LoseEfficacyTime >= DateTime.Now)
                .Where(p => p.IsArrive == true)
                .Where(p => SqlFunc.JsonListObjectAny(p.PushRanges, "Key", dto.PushRanges))
                .Where(p => p.BulletinTypeId == dto.NoticeType)
                .WhereIF(!string.IsNullOrEmpty(dto.Condition), p => p.Title.Contains(dto.Condition))
                .Select(it => new ArticleListDto
                {
                    Page = 0,
                    NoticeID = it.Id,
                    //NoticeContent = it.Content,
                    NoticeTypeName = it.BulletinTypeName,
                    NoticeTitle = it.Title,
                    NoticeBMName = it.SourceOrgName,
                    NoticeCreateDate = it.CreationTime,
                    VideoUrl = "",
                    WNLT_FullCode = ""
                });

            List<ArticleListDto> items = new List<ArticleListDto>();
            if (dto.NoticeType == "6")
            {
                //知识库
                var items2 = _knowledgeRepository.Queryable()
                    .Where(k => k.IsPublic == true)
                    .Where(k => k.Status == EKnowledgeStatus.OnShelf)
                    .Where(k => k.Attribution == "部门知识库")
                    .Select(it => new ArticleListDto
                    {
                        Page = 0,
                        NoticeID = it.Id,
                        //NoticeContent = it.Content,
                        NoticeTypeName = "知识库",
                        NoticeTitle = it.Title,
                        NoticeBMName = it.CreatorOrgName,
                        NoticeCreateDate = it.CreationTime,
                        VideoUrl = "",
                        WNLT_FullCode = ""
                    });

                items = await _orderRepository.UnionAll(items1, items2)
                  .Select(x => new ArticleListDto
                  {
                      Page = SqlFunc.RowNumber($"{x.NoticeCreateDate} desc "),
                      NoticeID = x.NoticeID,
                      //NoticeContent = x.NoticeContent,
                      NoticeTypeName = x.NoticeTypeName,
                      NoticeTitle = x.NoticeTitle,
                      NoticeBMName = x.NoticeBMName,
                      NoticeCreateDate = x.NoticeCreateDate,
                      VideoUrl = x.VideoUrl,
                      WNLT_FullCode = x.WNLT_FullCode
                  })
                  .OrderByDescending(p => p.NoticeCreateDate)
                  .ToPageListAsync(dto.PageIndex, dto.PageSize, total);
            }
            else
            {
                items = await items1
                  .OrderByDescending(p => p.NoticeCreateDate)
                  .ToPageListAsync(dto.PageIndex, dto.PageSize, total);

            }

            //计算总页数
            int nPageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(total) / dto.PageSize));
            ArticleListDataDto dataDto = new()
            {
                PageCount = nPageCount,
                Total = total,
                data = _mapper.Map<IReadOnlyList<ArticleListDto>>(items)
            };

            return OpenResponse.Ok(WebPortalDeResponse<ArticleListDataDto>.Success(dataDto));
        }

        /// <summary>
        /// 获取详情，修改阅读次数
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getarticledetails_yibin")]
        public async Task<OpenResponse> GetArticleDetailsYiBin([FromBody] ArticleIdDto dto)
        {
            ArticleDetailsDto detailsDto = null;
            if (dto.TypeName == "知识库")
            {
                var data = await _knowledgeRepository.GetAsync(p => p.Id == dto.Id, HttpContext.RequestAborted);
                if (data != null)
                {
                    data.PageView = data.PageView + 1;
                    await _knowledgeRepository.UpdateAsync(data, HttpContext.RequestAborted);
                    detailsDto = new()
                    {
                        NoticeID = data.Id,
                        NoticeTypeName = "知识库",
                        NoticeTitle = data.Title,
                        NoticeBMName = data.CreatorOrgName,
                        NoticeCreateDate = data.CreationTime,
                        NoticeRCount = data.PageView,
                        WNED_VideoUrl = "",
                        NoticeContent = data.Content
                    };
                    if (data != null && !string.IsNullOrEmpty(data.Content))
                        data.Content = _bulletinApplication.GetSiteUrls(data.Content);
                }
                else
                    detailsDto = new();
            }
            else
            {
                var data = await _bulletinRepository.GetAsync(p => p.Id == dto.Id, HttpContext.RequestAborted);
                if (data != null)
                {
                    data.ReadedNum = data.ReadedNum + 1;
                    await _bulletinRepository.UpdateAsync(data, HttpContext.RequestAborted);
                    detailsDto = new()
                    {
                        NoticeID = data.Id,
                        NoticeTypeName = data.BulletinTypeName,
                        NoticeTitle = data.Title,
                        NoticeBMName = data.SourceOrgName,
                        NoticeCreateDate = data.CreationTime,
                        NoticeRCount = data.ReadedNum,
                        WNED_VideoUrl = "",
                        NoticeContent = data.Content
                    };
                    if (data != null && !string.IsNullOrEmpty(data.Content))
                        data.Content = _bulletinApplication.GetSiteUrls(data.Content);
                }
                else
                    detailsDto = new();
            }

            List<ArticleDetailsDto> dataDto = new() { detailsDto };
            return OpenResponse.Ok(WebPortalDeResponse<IReadOnlyList<ArticleDetailsDto>>.Success(dataDto));
        }

        /// <summary>
        /// 上一条和下一条
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getpreviousandnext_yibin")]
        public async Task<OpenResponse> GetPreviousAndNextYiBin([FromBody] ArticlePreviousAndNextDto dto)
        {
            if (string.IsNullOrEmpty(dto.PushRanges))
                dto.PushRanges = "2";

            var sugar = _bulletinRepository.Queryable()
                .Where(p => p.LoseEfficacyTime >= DateTime.Now)
                .Where(p => p.IsArrive == true)
                .Where(p => SqlFunc.JsonListObjectAny(p.PushRanges, "Key", dto.PushRanges));

            if (dto.FullSearch == "1")//全文搜索
            {
                if (_appOptions.Value.IsYiBin)
                {
                    sugar.Where(p => p.BulletinTypeId == "1" || p.BulletinTypeId == "5" || p.BulletinTypeId == "6" || p.BulletinTypeId == "7" || p.BulletinTypeId == "3" || p.BulletinTypeId == "4")
                    .WhereIF(!string.IsNullOrEmpty(dto.Condition), p => p.Content.Contains(dto.Condition) || p.Title.Contains(dto.Condition));
                }
                if (_appOptions.Value.IsZiGong)
                {
                    sugar.Where(p => p.BulletinTypeId == "5013" || p.BulletinTypeId == "5016" || p.BulletinTypeId == "5011" || p.BulletinTypeId == "5015" || p.BulletinTypeId == "5017")
                    .WhereIF(!string.IsNullOrEmpty(dto.Condition), p => p.Content.Contains(dto.Condition) || p.Title.Contains(dto.Condition));
                }
            }
            else//指定分类
            {
                sugar.WhereIF(!string.IsNullOrEmpty(dto.Condition), p => p.Title.Contains(dto.Condition))
                    .Where(p => p.BulletinTypeId == dto.NoticeTypeId);
            }

            var items1 = sugar.Select(it => new ArticleDetailDataDto
            {
                Page = SqlFunc.RowNumber($"{it.CreationTime} desc "),// SqlFunc.MappingColumn(default(int), "  row_number()  over( order by 'NoticeCreateDate'  ) "),
                NoticeID = it.Id,
                NoticeTitle = it.Title,
                NoticeTypeName = it.BulletinTypeName,
                NoticeCreateDate = it.CreationTime
            });

            List<ArticleDetailDataDto> list = new List<ArticleDetailDataDto>();
            if (dto.NoticeTypeId == "6")
            {
                //知识库
                var items2 = _knowledgeRepository.Queryable()
                    .Where(k => k.IsPublic == true)
                    .Where(k => k.Status == EKnowledgeStatus.OnShelf)
                    .Where(k => k.Attribution == "部门知识库")
                    .WhereIF(!string.IsNullOrEmpty(dto.Condition), k => k.Content.Contains(dto.Condition) || k.Title.Contains(dto.Condition))
                    .Select(it => new ArticleDetailDataDto
                    {
                        Page = 0,
                        NoticeID = it.Id,
                        NoticeTitle = it.Title,
                        NoticeTypeName = "知识库",
                        NoticeCreateDate = it.CreationTime
                    });

                list = await _orderRepository.UnionAll(items1, items2)
                    .Select(x => new ArticleDetailDataDto
                    {
                        Page = SqlFunc.RowNumber($"{x.NoticeCreateDate} desc "),
                        NoticeID = x.NoticeID,
                        NoticeTitle = x.NoticeTitle,
                        NoticeTypeName = x.NoticeTypeName,
                        NoticeCreateDate = x.NoticeCreateDate
                    })
                    .OrderByDescending(x => x.NoticeCreateDate)
                    .ToListAsync();
            }
            else
            {
                list = await items1.OrderByDescending(x => x.NoticeCreateDate).ToListAsync();
            }

            //数据为空返回空数据
            if (list == null || list.Count == 0)
                return OpenResponse.Ok(WebPortalDeResponse<List<ArticlePreviousAndNextDataDto>>.Success(null));
            else
            {
                var temp = list.Find(p => p.NoticeID == dto.ID);
                if (temp != null)
                {
                    List<ArticlePreviousAndNextDataDto> returnDto = new();
                    //上一条
                    var pTemp = list.Find(p => p.Page == temp.Page - 1);
                    if (pTemp != null)

                        returnDto.Add(new()
                        {
                            NoticeID = pTemp.NoticeID,
                            NoticeTitle = pTemp.NoticeTitle,
                            NoticeTypeName = pTemp.NoticeTypeName,
                            pntype = "p"
                        });

                    //下一条
                    var nTemp = list.Find(p => p.Page == temp.Page + 1);
                    if (nTemp != null)
                        returnDto.Add(new()
                        {
                            NoticeID = nTemp.NoticeID,
                            NoticeTitle = nTemp.NoticeTitle,
                            NoticeTypeName = nTemp.NoticeTypeName,
                            pntype = "n"
                        });
                    return OpenResponse.Ok(WebPortalDeResponse<List<ArticlePreviousAndNextDataDto>>.Success(returnDto));
                }
                else
                    return OpenResponse.Ok(WebPortalDeResponse<List<ArticlePreviousAndNextDataDto>>.Success(null));
            }
        }

        /// <summary>
        /// 全文检索
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getfulltextsearchlist_yibin")]
        public async Task<OpenResponse> GetFullTextSearchList_YiBin([FromBody] QueryArticleListDto dto)
        {
            if (string.IsNullOrEmpty(dto.PushRanges))
                dto.PushRanges = "2";

            if (string.IsNullOrEmpty(dto.Condition))
                return OpenResponse.Ok(WebPortalDeResponse<FullTextSearchListDataDto>.Success(null));

            RefAsync<int> total = 0;
            var items1 = _bulletinRepository.Queryable()
                 .Where(p => p.LoseEfficacyTime >= DateTime.Now)
                 .Where(p => p.IsArrive == true)
                 .Where(p => SqlFunc.JsonListObjectAny(p.PushRanges, "Key", dto.PushRanges))
                 .WhereIF(_appOptions.Value.IsYiBin, p => p.BulletinTypeId == "1" || p.BulletinTypeId == "5" || p.BulletinTypeId == "6" || p.BulletinTypeId == "7" || p.BulletinTypeId == "3" || p.BulletinTypeId == "4")
                 .WhereIF(_appOptions.Value.IsZiGong, p => p.BulletinTypeId == "5013" || p.BulletinTypeId == "5016" || p.BulletinTypeId == "5011" || p.BulletinTypeId == "5015" || p.BulletinTypeId == "5017")
                 .WhereIF(!string.IsNullOrEmpty(dto.Condition), p => p.Title.Contains(dto.Condition))
                 .OrderByDescending(p => p.CreationTime)
                 .Select(it => new FullTextSearchListDto
                 {
                     Page = 0,
                     NoticeID = it.Id,
                     //Content = it.Content,
                     NoticeTypeID = it.BulletinTypeId,
                     NoticeTypeName = it.BulletinTypeName,
                     NoticeTitle = it.Title,
                     NoticeBMName = it.SourceOrgName,
                     NoticeCreateDate = it.CreationTime.ToString("yyyy-MM-dd HH:mm:ss"),
                     TypeCode = ""
                 });

            List<FullTextSearchListDto> items = new List<FullTextSearchListDto>();
            if (dto.NoticeType == "6")
            {
                //知识库
                var items2 = _knowledgeRepository.Queryable()
                    .Where(k => k.IsPublic == true)
                    .Where(k => k.Status == EKnowledgeStatus.OnShelf)
                    .Where(k => k.Attribution == "部门知识库")
                    .WhereIF(!string.IsNullOrEmpty(dto.Condition), k => k.Content.Contains(dto.Condition) || k.Title.Contains(dto.Condition))
                    .Select(it => new FullTextSearchListDto
                    {
                        Page = 0,
                        NoticeID = it.Id,
                        //NoticeContent = it.Content,
                        NoticeTypeID = "6",
                        NoticeTypeName = "知识库",
                        NoticeTitle = it.Title,
                        NoticeBMName = it.CreatorOrgName,
                        NoticeCreateDate = it.CreationTime.ToString("yyyy-MM-dd HH:mm:ss"),
                        TypeCode = ""
                    });

                items = await _orderRepository.UnionAll(items1, items2)
                  .Select(x => new FullTextSearchListDto
                  {
                      Page = SqlFunc.RowNumber($"{x.NoticeCreateDate} desc "),
                      NoticeID = x.NoticeID,
                      //NoticeContent = it.Content,
                      NoticeTypeID = x.NoticeTypeID,
                      NoticeTypeName = x.NoticeTypeName,
                      NoticeTitle = x.NoticeTitle,
                      NoticeBMName = x.NoticeBMName,
                      NoticeCreateDate = x.NoticeCreateDate,
                      TypeCode = ""
                  })
                  .OrderByDescending(p => p.NoticeCreateDate)
                  .ToPageListAsync(dto.PageIndex, dto.PageSize, total);
            }
            else
            {
                items = await items1
                  .OrderByDescending(p => p.NoticeCreateDate)
                  .ToPageListAsync(dto.PageIndex, dto.PageSize, total);
            }

            //计算总页数
            int nPageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(total) / dto.PageSize));
            FullTextSearchListDataDto dataDto = new()
            {
                PageCount = nPageCount,
                data = _mapper.Map<IReadOnlyList<FullTextSearchListDto>>(items)
            };
            return OpenResponse.Ok(WebPortalDeResponse<FullTextSearchListDataDto>.Success(dataDto));
        }

        #endregion

        #region 办件-宜宾

        /// <summary>
        /// 办件摘编详情
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getorderdetailbyid_yibin")]
        public async Task<object> GetOrderDetailByIdYiBin([FromBody] ArticleIdDto dto)
        {
            var data = await _orderRepository.GetAsync(p => p.Id == dto.Id, HttpContext.RequestAborted);

            var orderDetail = _mapper.Map<OrderDetail>(data);
            if (data != null)
            {
                //如果是省工单或者是省政民互动的工单，市民不能进行评价
                if (data.IsProvince == true || data.SourceChannelCode == "ZMHD")
                    orderDetail.IsProvinceOrder = "1";
                else
                    orderDetail.IsProvinceOrder = "0";

                //获取发布的数据
                var orderPublish = await _orderPublishRepository.GetAsync(p => p.OrderId == data.Id, HttpContext.RequestAborted);
                if (orderPublish != null)
                {
                    orderDetail.PubFlag = "1";
                    orderDetail.FlowTitle = orderPublish.ArrangeTitle;
                    orderDetail.FlowContent = orderPublish.ArrangeContent;
                    orderDetail.FlowResult = orderPublish.ArrangeOpinion;
                    if (orderPublish.PublishState)
                        orderDetail.FlowPubFlagName = "公开";
                    orderDetail.FirstVisitResult = data.FirstVisitResult;
                }

                // 工单流转到部门才允许显示办理内容
                if (data.ActualHandleOrgCode == OrgSeedData.CenterId && data.Status < EOrderStatus.Published)
                {
                    orderDetail.FlowContent = "信件正在办理中...";
                    orderDetail.FlowResult = "信件正在办理中...";
                }

                //能否进行评价
                var orderVisit = await _orderVisitRepository.GetAsync(p => p.OrderId == data.Id && p.VisitState != EVisitState.None, HttpContext.RequestAborted);
                if (orderVisit == null)
                    orderDetail.VisitType = "0";
                else
                {
                    orderDetail.VisitType = orderVisit.VisitState switch
                    {
                        EVisitState.WaitForVisit or EVisitState.SMSVisiting or EVisitState.SMSUnsatisfied => "1",
                        EVisitState.Visited => "2",
                        EVisitState.Visiting or EVisitState.NoSatisfiedWaitForVisit or EVisitState.None => "0",
                        _ => "0",
                    };
                }



            }
            //List<OrderDetail> dataDto = new() { orderDetail };
            //return OpenResponse.Ok(WebPortalDeResponse<IReadOnlyList<OrderDetail>>.Success(dataDto));

            var dissatisfiedReason = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.DissatisfiedReason);

            return new
            {
                OrderDetail = orderDetail,
                DissatisfiedReason = dissatisfiedReason
            };
        }

        #endregion

        #region 评价-宜宾

        /// <summary>
        /// 评价内容
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("receivevisitdata_yibin")]
        public async Task<OpenResponse> ReceiveVisitData_YiBin([FromBody] OrderVisitListDataDto dto)
        {
            if (dto == null || dto.VistListDtos == null || dto.VistListDtos.Count == 0)
                return OpenResponse.Ok(WebPortalDeResponse<string>.Failed("评价数据不能为空！"));

            var dataOrder = await _orderVisitRepository.GetAsync(p => p.OrderId == dto.OrderId && p.VisitState != EVisitState.None, HttpContext.RequestAborted);
            if (dataOrder == null)
                return OpenResponse.Ok(WebPortalDeResponse<string>.Failed("工单已经评价！"));

            //组装数据
            OrderVisitWebDto visitWebDto = new()
            {
                VisitType = Hotline.Share.Enums.Order.EVisitType.WebVisit,
                VisitTime = DateTime.Now
            };

            List<OrderVisitDetailWebDto> orderVisitDetails = new();

            #region 部门评价
            //部门评价
            //遍历数据
            foreach (var item in dto.VistListDtos)
            {
                Hotline.Share.Dtos.Kv kv = item.SatisfactionCode switch
                {
                    "5" => new Hotline.Share.Dtos.Kv { Key = "5", Value = "非常满意" },
                    "4" => new Hotline.Share.Dtos.Kv { Key = "4", Value = "满意" },
                    "2" => new Hotline.Share.Dtos.Kv { Key = "2", Value = "不满意" },
                    _ => new Hotline.Share.Dtos.Kv { Key = "7", Value = "不做评价" },
                };
                //组装回访数据
                visitWebDto.Id = item.VisitId;
                OrderVisitDetailWebDto detailDto = new()
                {
                    Id = item.Id,
                    VisitTarget = Hotline.Share.Enums.Order.EVisitTarget.Org,
                    OrgProcessingResults = kv,
                    OrgNoSatisfiedReason = item.OrgNoSatisfiedReason,
                    OrgHandledAttitude = kv,
                    VisitContent = item.VisitContent,
                    IsContact = item.IsContact,
                    Volved = item.Volved
                };
                orderVisitDetails.Add(detailDto);
            }
            #endregion

            visitWebDto.OrderVisitDetailDto = orderVisitDetails;

            //推送数据
            await _orderApplication.OrderVisitWeb(visitWebDto, HttpContext.RequestAborted);
            return OpenResponse.Ok(WebPortalDeResponse<string>.Success("1"));
        }

        #endregion
    }
}
