using Hotline.Orders; using Hotline.Share.Dtos; using Hotline.Share.Dtos.Article; using Hotline.Share.Dtos.Snapshot; using Hotline.Share.Tools; using Hotline.Snapshot; using Hotline.Users; using SqlSugar; using XF.Domain.Authentications; using XF.Domain.Dependency; using XF.Domain.Repository; using Hotline.Repository.SqlSugar.Extensions; using Hotline.Share.Enums; using Hotline.Share.Enums.Order; using Hotline.Share.Requests; using Hotline.Share.Enums.Snapshot; using Mapster; using Hotline.Caching.Interfaces; using NPOI.Util.ArrayExtensions; using XF.Domain.Exceptions; using Hotline.Settings; using Hotline.Share.Dtos.Settings; using Hotline.File; using Hotline.Share.Enums.Article; using Hotline.Tools; using Hotline.Snapshot.Interfaces; using DotNetCore.CAP; using Microsoft.AspNetCore.Http; using Hotline.Share.Dtos.FlowEngine; using Hotline.FlowEngine.Workflows; using Hotline.Share.Enums.FlowEngine; namespace Hotline.Application.Snapshot; /// /// 随手拍应用层 /// public abstract class SnapshotApplicationBase { private readonly IThirdAccountRepository _thirdAccountRepository; private readonly IRepository _orderRepository; private readonly ISnapshotBulletinRepository _bulletinRepository; /// /// 行业 /// private readonly IRepository _industryRepository; private readonly IThirdIdentiyService _thirdLoginService; private readonly ISessionContext _sessionContext; private readonly IRepository _redPackRecordRepository; private readonly IRepository _orderSnapshotRepository; private readonly ISystemSettingCacheManager _systemSettingCacheManager; private readonly ISystemAreaDomainService _systemAreaDomainService; private readonly IFileRepository _fileRepository; private readonly ISystemDicDataCacheManager _systemDicDataCacheManager; private readonly ISnapshotOrderPublishRepository _snapshotOrderPublishRepository; private readonly IRepository _workflowTraceRepository; public SnapshotApplicationBase(IThirdIdentiyService thirdLoginService, IRepository industryRepository, ISnapshotBulletinRepository bulletinRepository, ISessionContext sessionContext, IRepository redPackRecordRepository, IRepository orderRepository, IThirdAccountRepository thirdAccountRepository, IRepository orderSnapshotRepository, ISystemSettingCacheManager systemSettingCacheManager, ISystemAreaDomainService systemAreaDomainService, IFileRepository fileRepository, ISystemDicDataCacheManager systemDicDataCacheManager, ISnapshotOrderPublishRepository snapshotOrderPublishRepository, IRepository workflowTraceRepository) { _thirdLoginService = thirdLoginService; _industryRepository = industryRepository; _bulletinRepository = bulletinRepository; _sessionContext = sessionContext; _redPackRecordRepository = redPackRecordRepository; _orderRepository = orderRepository; _thirdAccountRepository = thirdAccountRepository; _orderSnapshotRepository = orderSnapshotRepository; _systemSettingCacheManager = systemSettingCacheManager; _systemAreaDomainService = systemAreaDomainService; _fileRepository = fileRepository; _systemDicDataCacheManager = systemDicDataCacheManager; _snapshotOrderPublishRepository = snapshotOrderPublishRepository; _workflowTraceRepository = workflowTraceRepository; } /// /// 获取随手拍小程序首页数据 /// /// public async Task GetHomePageAsync() { var fileServiceUrl = _systemSettingCacheManager.FileServerUrl; var fileDownloadApi = fileServiceUrl + _systemSettingCacheManager.FileDownloadApi; var items = await _industryRepository.Queryable() .Where(m => m.IsEnable) .OrderBy(m => m.DisplayOrder) .ToListAsync(m => new HomeIndustryOutDto()); items.ForEach(m => { if (m.BackgroundImgUrl.NotNullOrEmpty()) m.BackgroundImgUrl = fileDownloadApi + m.BackgroundImgUrl; if (m.BannerImgUrl.NotNullOrEmpty()) m.BannerImgUrl = fileDownloadApi + m.BannerImgUrl; if (m.CareCellImgUrl.NotNullOrEmpty()) m.CareCellImgUrl = fileDownloadApi + m.CareCellImgUrl; if (m.CellImgUrl.NotNullOrEmpty()) m.CellImgUrl = fileDownloadApi + m.CellImgUrl; }); return new HomePageOutDto { Banners = _systemSettingCacheManager.AppBanner.Split('|').Select(m => fileDownloadApi + m).ToList(), Industrys = items }; } /// /// 获取行业集合 /// /// public async Task> GetIndustresAsync() { var fileServiceUrl = _systemSettingCacheManager.FileServerUrl; var fileDownloadApi = fileServiceUrl + _systemSettingCacheManager.FileDownloadApi; var items = await _industryRepository.Queryable() .Where(m => m.IsEnable) .OrderBy(m => m.DisplayOrder) .ToListAsync(m => new IndustryOutDto()); return items; } /// /// 行业页面基础数据 /// /// /// /// public async Task GetIndustryBaseAsync(string id, CancellationToken requestAborted) { var fileServiceUrl = _systemSettingCacheManager.FileServerUrl; var fileDownloadApi = fileServiceUrl + _systemSettingCacheManager.FileDownloadApi; var indurstry = await _industryRepository.GetAsync(id, requestAborted) ?? throw UserFriendlyException.SameMessage("行业不存在:" + id); var bulletinId = await _bulletinRepository.Queryable() .Where(m => m.SnapshotBulletinTypeId == indurstry.BulletinTypeGuideId && m.BulletinState == EBulletinState.ReviewPass && m.IsArrive == true) .OrderByDescending(m => m.CreationTime) .Select(m => m.Id) .FirstAsync(requestAborted); var outDto = new IndustryBaseOutDto { Industry = indurstry.Adapt() }; outDto.BulletinId = bulletinId; if (indurstry.IndustryType == EIndustryType.Declare) { outDto.AreaTree = (await _systemAreaDomainService.GetAreaTree(parentId: "510300")).Adapt>(); outDto.Files = (await _fileRepository.GetByKeyAsync(indurstry.Id, requestAborted)).Adapt>(); outDto.Files.ToList().ForEach(m => m.Url = fileDownloadApi + m.AdditionId); outDto.WorkplaceName = _systemDicDataCacheManager.WorkplaceName; outDto.Workplace = _systemDicDataCacheManager.Workplace; outDto.JobType = _systemDicDataCacheManager.JobType; outDto.BusinessUnitType = _systemDicDataCacheManager.BusinessUnitType; } return outDto; } public async Task AddOrderPublishAsync(AddSnapshotOrderPublishInDto dto, CancellationToken cancellation) { dto.ValidateObject(); var snapshotOrder = await _orderSnapshotRepository.GetAsync(dto.OrderId) ?? throw UserFriendlyException.SameMessage("工单不存在"); var order = await _orderRepository.Queryable() .Where(m => m.Id == dto.OrderId) .Select(m => new { m.Id, m.No }) .FirstAsync(cancellation) ?? throw UserFriendlyException.SameMessage("工单不存在"); var entity = dto.Adapt(); entity.Id = order.Id; entity.IndustryId = snapshotOrder.IndustryId; entity.IndustryName = snapshotOrder.IndustryName; entity.No = order.No; await _snapshotOrderPublishRepository.AddAsync(entity); } /// /// 获取公开工单集合 /// /// /// /// public async Task> GetOrderPublishAsync(OrderPublishInDto dto, CancellationToken requestAborted) { dto.ValidateObject(); var items = await _snapshotOrderPublishRepository.Queryable() .Where(m => m.IndustryId == dto.IndustryId) .WhereIF(dto.Keyword.NotNullOrEmpty(), m => m.No.Contains(dto.Keyword) || m.ArrangeTitle.Contains(dto.Keyword)) .Select() .ToFixedListAsync(dto, requestAborted); return items; } /// /// 获取公开的工单详情 /// /// /// /// public async Task GetOrderPublishDetailAsync(string id, CancellationToken requestAborted) { var publish = await _snapshotOrderPublishRepository.GetAsync(id) ?? throw UserFriendlyException.SameMessage("工单不存在"); var outDto = publish.Adapt(); var fileServiceUrl = _systemSettingCacheManager.FileServerUrl; if (outDto.FileJson != null) { foreach (var item in outDto.FileJson) { item.Path = fileServiceUrl + item.Path; } } var traces = await _workflowTraceRepository.Queryable() .Where(m => m.ExternalId == publish.OrderId && m.Status == EWorkflowStepStatus.Handled) .OrderBy(m => m.AcceptTime) .ToListAsync(requestAborted); var centre = traces.Where(m => m.StepType == EStepType.End || m.StepType == EStepType.Start || m.BusinessType == EBusinessType.Send || m.BusinessType == EBusinessType.Seat || m.BusinessType == EBusinessType.File) .Select(m => new SnapshotWorkflow(m.Id, m.Name, m.HandleTime.Value)) .ToList(); outDto.Workflow = traces.Where(m => !centre.Select(s => s.Id).ToList().Contains(m.Id)) .Select(m => new SnapshotWorkflow(m.Id, m.Name, m.HandleTime.Value)) .ToList(); outDto.Workflow.AddRange(centre); outDto.Workflow = outDto.Workflow.OrderBy(m => m.HandleTime).ToList(); return outDto; } /// /// 获取随手拍小程序公告 /// /// public async Task> GetBulletinsAsync(BulletinInDto dto, CancellationToken cancellationToken) { var items = await _bulletinRepository.Queryable() .Where(m => m.BulletinState == EBulletinState.ReviewPass) .LeftJoin((bulletin, industry) => bulletin.SnapshotBulletinTypeId == industry.BulletinTypePublicityId) .Where((bulletin, industry) => industry.Id == dto.IndustryId) .ToFixedListAsync(dto, cancellationToken); return items.Adapt>(); } /// /// 获取个人中心数据 /// /// public async Task GetSnapshotUserInfoAsync() { var openId = _sessionContext.OpenId; var thirdAccount = await _thirdAccountRepository.QueryByOpenIdAsync(openId); var dayTime = DateTime.Now; var readPack = await _redPackRecordRepository.Queryable() .Where(m => m.WXOpenId == openId && m.PickupStatus == ERedPackPickupStatus.Received) .Where(m => m.CreationTime.Date == dayTime.Date) .Select(m => SqlFunc.AggregateSum(m.Amount)) .FirstAsync(); var outDto = await _orderRepository.Queryable() .Where(m => m.Contact == thirdAccount.PhoneNumber) .Select(m => new SnapshotUserInfoOutDto { NoReplyCount = SqlFunc.AggregateSum(SqlFunc.IIF(m.Status < EOrderStatus.Filed, 1, 0)), ReplyCount = SqlFunc.AggregateSum(SqlFunc.IIF(m.Status >= EOrderStatus.Filed, 1, 0)), AppraiseCount = SqlFunc.AggregateSum(SqlFunc.IIF(m.Status == EOrderStatus.Visited, 1, 0)), }).FirstAsync(); outDto.DayAmount = readPack; outDto.TotalAmount = thirdAccount.TotalAmount; outDto.PhoneNumber = thirdAccount.PhoneNumber; return outDto; } /// /// 获取工单列表 /// public async Task> GetSnapshotOrdersAsync(OrderInDto dto, CancellationToken cancellationToken) { var items = await _orderSnapshotRepository.Queryable() .LeftJoin((snapshot, order) => snapshot.Id == order.Id) .Where((snapshot, order) => order.Contact == _sessionContext.Phone) .WhereIF(dto.Status == EOrderQueryStatus.Appraise, (snapshot, order) => order.Status == EOrderStatus.Visited) .WhereIF(dto.Status == EOrderQueryStatus.NoReply, (snapshot, order) => order.Status < EOrderStatus.Filed) .WhereIF(dto.Status == EOrderQueryStatus.Reply, (snapshot, order) => order.Status >= EOrderStatus.Filed) .WhereIF(dto.KeyWords.NotNullOrEmpty(), (snapshot, order) => order.Title.Contains(dto.KeyWords)) .Select((snapshot, order) => new OrderOutDto { Id = snapshot.Id, OrderNo = order.No, Title = order.Title, Status = order.Status, IndustryName = snapshot.IndustryName, CreationTime = order.CreationTime, Area = order.City }) .ToFixedListAsync(dto, cancellationToken); return items; } /// /// 获取工单详情 /// /// /// public async Task GetSnapshotOrderDetailAsync(string id, CancellationToken cancellationToken) { var order = await _orderRepository.GetAsync(id) ?? throw UserFriendlyException.SameMessage("工单不存在"); var outDto = order.Adapt(); var fileServiceUrl = _systemSettingCacheManager.FileServerUrl; if (outDto.FileJson != null) { foreach (var item in outDto.FileJson) { item.Path = fileServiceUrl + item.Path; } } var traces = await _workflowTraceRepository.Queryable() .Where(m => m.ExternalId == order.Id && m.Status == EWorkflowStepStatus.Handled) .OrderBy(m => m.AcceptTime) .ToListAsync(cancellationToken); var centre = traces.Where(m => m.StepType == EStepType.End || m.StepType == EStepType.Start || m.BusinessType == EBusinessType.Send || m.BusinessType == EBusinessType.Seat || m.BusinessType == EBusinessType.File) .Select(m => new SnapshotWorkflow(m.Id, m.Name, m.HandleTime.Value)) .ToList(); outDto.Workflow = traces.Where(m => !centre.Select(s => s.Id).ToList().Contains(m.Id)) .Select(m => new SnapshotWorkflow(m.Id, m.Name, m.HandleTime.Value)) .ToList(); outDto.Workflow.AddRange(centre); outDto.Workflow = outDto.Workflow.OrderBy(m => m.HandleTime).ToList(); return outDto; } /// /// 获取当月详细红包列表 /// /// /// public async Task> GetRedPacksAsync(RedPacksInDto dto, CancellationToken cancellationToken) { var items = await _redPackRecordRepository.Queryable(includeDeleted: true) .Where(m => m.IsDeleted == false) .Where(m => m.WXOpenId == _sessionContext.OpenId) .Where(m => m.PickupStatus == dto.Status) .Where(m => m.CreationTime.ToString("yyyy-MM") == dto.Time) .LeftJoin((red, order) => red.OrderId == order.Id) .Select((red, order) => new RedPackOutDto { Amount = red.Amount, Title = order.Title, CreationTime = red.CreationTime }) .ToFixedListAsync(dto, cancellationToken); return items; } /// /// 按月统计红包金额 /// /// /// public async Task> GetRedPackDateAsync(RedPackDateInDto dto) { var openId = _sessionContext.OpenId; var item = await _redPackRecordRepository.Queryable() .Where(m => m.WXOpenId == openId) .Where(m => m.PickupStatus == dto.Status) .GroupBy(m => m.CreationTime.ToString("yyyy-MM")) .OrderByDescending(m => m.CreationTime) .Select(m => new RedPackDateOutDto { CreationTime = SqlFunc.AggregateMax(m.CreationTime.Date), Amount = SqlFunc.AggregateSum(m.Amount) }) .Take(dto.Count) .ToListAsync(); return item; } /// /// 获取随手拍公告详情 /// /// /// public async Task GetBulletinsDetailAsync(string id) { var detail = await _bulletinRepository.Queryable() .Where(m => m.Id == id) .Where(m => m.BulletinState == Share.Enums.Article.EBulletinState.ReviewPass) .Select(m => new BulletinOutDto { Id = m.Id, Title = m.Title, Content = m.Content, CreationTime = m.CreationTime }) .FirstAsync(); return detail; } /// /// 添加随手拍公告 /// /// public async Task AddBulletinAsync(AddSnapshotBulletinInDto dto) { dto.ValidateObject(); var entity = dto.Adapt(); entity.BulletinState = EBulletinState.InReview; entity.Id = await _bulletinRepository.AddAsync(entity); return entity.Id; } /// /// 审核公告 /// /// /// public async Task AuditBulletinAsync(ExamineBulletinDto dto) { var bulletin = await _bulletinRepository.GetAsync(dto.Id) ?? throw UserFriendlyException.SameMessage("无效数据"); if (bulletin.BulletinState != EBulletinState.InReview) throw UserFriendlyException.SameMessage("当前状态不能审核"); bulletin.ExaminOpinion = dto.Reason; bulletin.ExaminTime = DateTime.Now; bulletin.ExaminManId = _sessionContext.RequiredUserId; if (dto.IsPass) { bulletin.BulletinState = EBulletinState.ReviewPass; } else { bulletin.BulletinState = EBulletinState.ReviewNoPass; } await _bulletinRepository.UpdateAsync(bulletin); } }