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