using DotNetCore.CAP;
using Hotline.Article;
using Hotline.Orders;
using Hotline.Settings.Hotspots;
using Hotline.Share.Dtos.Push.FWMessage;
using Hotline.Share.Dtos.Push;
using Hotline.Share.Dtos.WebPortal;
using Hotline.Share.Enums.Order;
using Hotline.WebPortal;
using MapsterMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using XF.Domain.Filters;
using XF.Domain.Repository;
using XF.Domain.Cache;
using Hotline.Push.Notifies;
using Hotline.Share.Enums.Push;
using StackExchange.Redis;
using MediatR;
using XF.Domain.Constants;
using Hotline.Caching.Interfaces;
using Hotline.Application.Orders;
using XF.Domain.Authentications;
using Hotline.Share.Dtos.DataSharing.PusherHotlineDto;
using Hotline.Share.Dtos.Order;
using Org.BouncyCastle.Ocsp;
using System.Threading;
using Hotline.Settings;

namespace Hotline.Api.Controllers
{
    public class WebPortalController : BaseController
    {
        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;


        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
            )
        {
            _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;
        }

        #region 通知
        /// <summary>
        /// 获取列表
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("getarticlelist")]
        public async Task<OpenResponse> GetArticleList([FromBody] QueryArticleListDto dto)
        {
            RefAsync<int> total = 0;
            var items = await _bulletinRepository.Queryable()
                .Where(p => p.LoseEfficacyTime >= DateTime.Now)
                .Where(d => SqlFunc.JsonListObjectAny(d.PushRanges, "Key", "2"))
                 .Where(p => p.BulletinTypeId == dto.NoticeType)
                 .WhereIF(!string.IsNullOrEmpty(dto.Condition), p => p.Title.Contains(dto.Condition))
                 .OrderByDescending(p => p.BulletinTime)
                 .Select(it => new
                 {
                     Page = SqlFunc.RowNumber($"{it.BulletinTime} 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.BulletinTime,
                     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,
                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)
        {
            var items = await _bulletinRepository.Queryable()
                .Where(p => p.LoseEfficacyTime >= DateTime.Now)
                .Where(d => SqlFunc.JsonListObjectAny(d.PushRanges, "Key", "2"))
                 .Where(p => p.BulletinTypeId == dto.BulletinTypeId)
                 .WhereIF(!string.IsNullOrEmpty(dto.CheckChar), p => p.Content.Contains(dto.CheckChar))
                 .OrderByDescending(p => p.BulletinTime)
                 .Select(it => new
                 {
                     DataID = it.Id,
                     it.Title,
                     CreateDate = it.BulletinTime,
                     it.Content
                 })
                 .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.BulletinTime,
                    NoticeRCount = data.ReadedNum,
                    WNED_VideoUrl = "",
                    NoticeContent = 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")]
        public async Task<OpenResponse> GetPreviousAndNext([FromBody] ArticlePreviousAndNextDto dto)
        {
            var sugar = _bulletinRepository.Queryable()
                .Where(p => p.LoseEfficacyTime >= DateTime.Now)
                .Where(d => SqlFunc.JsonListObjectAny(d.PushRanges, "Key", "2"))
                ;
            if (dto.FullSearch == "1")//全文搜索
            {
                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));
            }
            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.BulletinTime)
                .Select(it => new
                {
                    Page = SqlFunc.RowNumber($"{it.BulletinTime} desc "),// SqlFunc.MappingColumn(default(int), "  row_number()  over( order by 'NoticeCreateDate'  ) "),
                    NoticeID = it.Id,
                    NoticeTitle = it.Title,
                    NoticeCreateDate = it.BulletinTime
                })
                .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.Condition))
                return OpenResponse.Ok(WebPortalDeResponse<FullTextSearchListDataDto>.Success(null));

            RefAsync<int> total = 0;
            var items = await _bulletinRepository.Queryable()
                .Where(p => p.LoseEfficacyTime >= DateTime.Now)
                .Where(d => SqlFunc.JsonListObjectAny(d.PushRanges, "Key", "2"))
                 .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.Title.Contains(dto.Condition))
                 .OrderByDescending(p => p.BulletinTime)
                 .Select(it => new
                 {
                     Page = SqlFunc.RowNumber($"{it.BulletinTime} desc "),
                     NoticeID = it.Id,
                     Content = it.Content,
                     NoticeTypeID = it.BulletinTypeId,
                     NoticeTypeName = it.BulletinTypeName,
                     NoticeTitle = it.Title,
                     NoticeBMName = it.SourceOrgName,
                     NoticeCreateDate = it.BulletinTime,
                     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(), "成功"));

        }
        #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 items = await _orderPublishRepository.Queryable()
               .Includes(p => p.Order)
                .Where(p => p.PublishState == true)
                .Where(p => p.Order.Id != null)
                .OrderByDescending(p => p.CreationTime)
               .Select(p => new
               {
                   DataID = p.OrderId,
                   Title = p.Order.Title,
                   CreateDate = p.CreationTime
               })
                .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 items = await _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)
                .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>
        [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 (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.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));
        }

        /// <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);
            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.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] WebFlowAccept dto)
        {
            var data = _mapper.Map<Hotline.Share.Dtos.Order.AddOrderDto>(dto);
            data.SourceChannel = "网站";
            data.SourceChannelCode = "WZ";
            data.Source = ESource.WebPortal;
            if (!string.IsNullOrEmpty(data.LicenceNo))
            {
                data.LicenceTypeCode = "10";
                data.LicenceType = "中华人民共和国居民身份证";
            }
            data.ExternalId = Guid.NewGuid().ToString();

            data.IdentityType = EIdentityType.Citizen;
            data.Transpond = false;
            data.IsEnforcementOrder = false;


            var result = await _orderApplication.ReceiveOrderFromExternalAsync(data, _sessionContext, 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;
                await _webFlowAcceptRepository.AddAsync(dto, 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.StartTime >= startDate && p.StartTime <= 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();

            //数据查询-查询总数前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()
            };

            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
    }
}
