OrderController.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. using Hotline.Application.FlowEngine;
  2. using Hotline.FlowEngine.Workflows;
  3. using Hotline.Orders;
  4. using Hotline.Repository.SqlSugar.Extensions;
  5. using Hotline.Settings;
  6. using Hotline.Share.Dtos;
  7. using Hotline.Share.Dtos.FlowEngine;
  8. using Hotline.Share.Dtos.Order;
  9. using Hotline.Share.Enums.Order;
  10. using Hotline.Share.Requests;
  11. using MapsterMapper;
  12. using Microsoft.AspNetCore.Authorization;
  13. using Microsoft.AspNetCore.Mvc;
  14. using XF.Domain.Authentications;
  15. using XF.Domain.Exceptions;
  16. using XF.Domain.Extensions;
  17. using XF.Utility.EnumExtensions;
  18. namespace Hotline.Api.Controllers;
  19. /// <summary>
  20. /// 工单
  21. /// </summary>
  22. public class OrderController : BaseController
  23. {
  24. private readonly IOrderDomainService _orderDomainService;
  25. private readonly IOrderRepository _orderRepository;
  26. private readonly IWorkflowApplication _workflowApplication;
  27. private readonly IWorkflowDomainService _workflowDomainService;
  28. private readonly IHotSpotTypeRepository _hotSpotTypeRepository;
  29. private readonly ISystemDomainService _systemDomainService;
  30. private readonly ISystemOrganizeRepository _organizeRepository;
  31. private readonly IMapper _mapper;
  32. public OrderController(
  33. IOrderDomainService orderDomainService,
  34. IOrderRepository orderRepository,
  35. IWorkflowApplication workflowApplication,
  36. IWorkflowDomainService workflowDomainService,
  37. IHotSpotTypeRepository hotSpotTypeRepository,
  38. ISystemDomainService systemDomainService,
  39. ISystemOrganizeRepository organizeRepository,
  40. IMapper mapper)
  41. {
  42. _orderDomainService = orderDomainService;
  43. _orderRepository = orderRepository;
  44. _workflowApplication = workflowApplication;
  45. _workflowDomainService = workflowDomainService;
  46. _hotSpotTypeRepository = hotSpotTypeRepository;
  47. _systemDomainService = systemDomainService;
  48. _organizeRepository = organizeRepository;
  49. _mapper = mapper;
  50. }
  51. /// <summary>
  52. /// 工单列表
  53. /// </summary>
  54. /// <param name="dto"></param>
  55. /// <returns></returns>
  56. [HttpGet]
  57. public async Task<PagedDto<OrderDto>> Query([FromQuery] QueryOrderDto dto)
  58. {
  59. var (total, items) = await _orderRepository.Queryable()
  60. .WhereIF(!string.IsNullOrEmpty(dto.Keyword), d => d.Title.Contains(dto.Keyword) || d.No.Contains(dto.Keyword))
  61. .WhereIF(!string.IsNullOrEmpty(dto.Content), d => d.Content.Contains(dto.Content))
  62. .WhereIF(dto.AcceptTypes.Any(), d => dto.AcceptTypes.Contains(d.AcceptType))
  63. .WhereIF(dto.Channels.Any(), d => dto.Channels.Contains(d.Channel))
  64. .WhereIF(dto.HotspotIds.Any(), d => dto.HotspotIds.Contains(d.HotspotId))
  65. .WhereIF(!string.IsNullOrEmpty(dto.TransferPhone), d => d.TransferPhone.Contains(dto.TransferPhone))
  66. .WhereIF(dto.OrgCodes.Any(), d => d.Workflow.Assigns.Any(s => dto.OrgCodes.Contains(s.OrgCode)))
  67. .WhereIF(!string.IsNullOrEmpty(dto.NameOrNo), d => d.Employee.Name.Contains(dto.NameOrNo) || d.Employee.StaffNo.Contains(dto.NameOrNo))
  68. .WhereIF(dto.CreationTimeStart.HasValue, d => d.CreationTime >= dto.CreationTimeStart)
  69. .WhereIF(dto.CreationTimeEnd.HasValue, d => d.CreationTime <= dto.CreationTimeEnd)
  70. .WhereIF(dto.EmergencyLevels.Any(), d => dto.EmergencyLevels.Contains(d.EmergencyLevel))
  71. .WhereIF(!string.IsNullOrEmpty(dto.PhoneNo), d => d.FromPhone.Contains(dto.PhoneNo) || d.Contact.Contains(dto.PhoneNo))
  72. .WhereIF(dto.PushType.HasValue, d => d.PushType == dto.PushType)
  73. .WhereIF(dto.ExpiredTimeStart.HasValue, d => d.ExpiredTime >= dto.ExpiredTimeStart)
  74. .WhereIF(dto.ExpiredTimeEnd.HasValue, d => d.ExpiredTime <= dto.ExpiredTimeEnd)
  75. .WhereIF(dto.Statuses.Any(), d => dto.Statuses.Contains(d.Status))
  76. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  77. return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
  78. }
  79. /// <summary>
  80. /// 历史工单
  81. /// </summary>
  82. /// <param name="dto"></param>
  83. /// <returns></returns>
  84. [HttpGet("history")]
  85. public async Task<PagedDto<OrderDto>> Query([FromQuery] PagedRequest dto)
  86. {
  87. var (total, items) = await _orderRepository.Queryable()
  88. .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);
  89. return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
  90. }
  91. /// <summary>
  92. /// 查询工单详情
  93. /// </summary>
  94. /// <param name="id"></param>
  95. /// <returns></returns>
  96. [HttpGet("{id}")]
  97. public async Task<OrderDto> Get(string id)
  98. {
  99. var order = await _orderRepository.Queryable()
  100. .Includes(d => d.OrderComplain)
  101. .Includes(d => d.OrderReport)
  102. .FirstAsync(d => d.Id == id);
  103. if (!string.IsNullOrEmpty(order.WorkflowId))
  104. order.Workflow = await _workflowDomainService.GetWorkflowAsync(order.WorkflowId, withSupplements: true, cancellationToken: HttpContext.RequestAborted);
  105. return _mapper.Map<OrderDto>(order);
  106. }
  107. /// <summary>
  108. /// 新增工单
  109. /// </summary>
  110. /// <param name="dto"></param>
  111. /// <returns></returns>
  112. [HttpPost]
  113. public async Task<string> Add([FromBody] AddOrderDto dto)
  114. {
  115. var order = _mapper.Map<Order>(dto);
  116. return await _orderDomainService.AddAsync(order, HttpContext.RequestAborted);
  117. }
  118. [HttpDelete("{id}")]
  119. public async Task Remove(string id)
  120. {
  121. var order = await _orderRepository.GetAsync(id, HttpContext.RequestAborted);
  122. if (order == null) return;
  123. if (order.Status != EOrderStatus.Temporary)
  124. throw UserFriendlyException.SameMessage("非草稿工单不可删除");
  125. await _orderRepository.RemoveAsync(order);
  126. }
  127. /// <summary>
  128. /// 更新工单信息
  129. /// </summary>
  130. /// <param name="dto"></param>
  131. /// <returns></returns>
  132. [HttpPut]
  133. public async Task Update([FromBody] UpdateOrderDto dto)
  134. {
  135. var order = await _orderRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
  136. if (order == null)
  137. throw UserFriendlyException.SameMessage("无效工单编号");
  138. if (order.Status != EOrderStatus.Temporary)
  139. throw UserFriendlyException.SameMessage("非草稿工单不可编辑");
  140. await _orderRepository.UpdateAsync(order, HttpContext.RequestAborted);
  141. }
  142. /// <summary>
  143. /// 开始流程
  144. /// </summary>
  145. /// <param name="id">工单id</param>
  146. /// <param name="dto">流程开启参数</param>
  147. /// <returns></returns>
  148. [HttpPost("{id}/startflow")]
  149. public async Task StartFlow(string id, [FromBody] StartWorkflowDto dto)
  150. {
  151. var order = await _orderRepository.GetAsync(id, HttpContext.RequestAborted);
  152. if (order == null)
  153. throw UserFriendlyException.SameMessage("无效工单编号");
  154. if (order.Status != EOrderStatus.Temporary || !string.IsNullOrEmpty(order.WorkflowId))
  155. throw UserFriendlyException.SameMessage("工单已发起流程");
  156. var workflowId = await _workflowApplication.StartWorkflowAsync(dto, HttpContext.RequestAborted);
  157. order.StartFlow(workflowId);
  158. await _orderRepository.UpdateAsync(order, HttpContext.RequestAborted);
  159. }
  160. /// <summary>
  161. /// 列表页面基础数据
  162. /// </summary>
  163. /// <returns></returns>
  164. [HttpGet("base-data")]
  165. public dynamic BaseData()
  166. {
  167. return new
  168. {
  169. AcceptTypeOptions = EnumExts.GetDescriptions<EAcceptType>(),
  170. ChannelOptions = EnumExts.GetDescriptions<EChannel>(),
  171. OrgsOptions = _organizeRepository.GetOrgJson(),
  172. EmergencyLevelOptions = EnumExts.GetDescriptions<EEmergencyLevel>(),
  173. PushTypeOptions = EnumExts.GetDescriptions<EPushType>(),
  174. OrderStatusOptions = EnumExts.GetDescriptions<EOrderStatus>(),
  175. };
  176. }
  177. /// <summary>
  178. /// 新增页面基础数据
  179. /// </summary>
  180. /// <returns></returns>
  181. [HttpGet("base-data-add")]
  182. public dynamic BaseDataAdd()
  183. {
  184. return new
  185. {
  186. ChannelOptions = EnumExts.GetDescriptions<EChannel>(),
  187. GenderOptions = EnumExts.GetDescriptions<EGender>(),
  188. IdentityTypeOptions = EnumExts.GetDescriptions<EIdentityType>(),
  189. LicenceTypeOptions = EnumExts.GetDescriptions<ELicenceType>(),
  190. AgeRangeOptions = _systemDomainService.GetSysDicDataByCode(SysDicTypeConsts.AgeRange),
  191. OrderTypeOptions = EnumExts.GetDescriptions<EOrderType>(),
  192. AcceptTypeOptions = EnumExts.GetDescriptions<EAcceptType>(),
  193. EmergencyLevelOptions = EnumExts.GetDescriptions<EEmergencyLevel>(),
  194. PushTypeOptions = EnumExts.GetDescriptions<EPushType>(),
  195. };
  196. }
  197. /// <summary>
  198. /// 扩展信息新增页面基础数据
  199. /// </summary>
  200. /// <returns></returns>
  201. [HttpGet("base-data-ext")]
  202. public dynamic BaseDataExtension()
  203. {
  204. return new
  205. {
  206. LicenceTypeOptions = _systemDomainService.GetSysDicDataByCode(SysDicTypeConsts.LicenceType),
  207. IdentityTypeOptions = _systemDomainService.GetSysDicDataByCode(SysDicTypeConsts.ProviderIdentityType),
  208. IdentityOptions = _systemDomainService.GetSysDicDataByCode(SysDicTypeConsts.Identity),
  209. NationalityOptions = _systemDomainService.GetSysDicDataByCode(SysDicTypeConsts.Nationality),
  210. NationOptions = _systemDomainService.GetSysDicDataByCode(SysDicTypeConsts.Nation),
  211. MarketTypeOptions = _systemDomainService.GetSysDicDataByCode(SysDicTypeConsts.MarketType),
  212. IndustryClassifyOptions = _systemDomainService.GetSysDicDataByCode(SysDicTypeConsts.IndustryClassify),
  213. BrandOptions = _systemDomainService.GetSysDicDataByCode(SysDicTypeConsts.Brand),
  214. ObjectClassifyOptions = _systemDomainService.GetSysDicDataByCode(SysDicTypeConsts.ObjectClassify),
  215. ComplainClassifyOptions = _systemDomainService.GetSysDicDataByCode(SysDicTypeConsts.ComplainClassify),
  216. SalesModeOptions = _systemDomainService.GetSysDicDataByCode(SysDicTypeConsts.SalesMode),
  217. ECommercePlatformOptions = _systemDomainService.GetSysDicDataByCode(SysDicTypeConsts.ECommercePlatform),
  218. ComplainTypeOptions = EnumExts.GetDescriptions<EComplainType>()
  219. };
  220. }
  221. /// <summary>
  222. /// 获取热点
  223. /// </summary>
  224. /// <param name="parentId">父级ID</param>
  225. /// <returns></returns>
  226. [HttpGet("hotspottype-list-parent")]
  227. public async Task<List<HotSpotType>> GetHotSpotType(string? parentId)
  228. {
  229. return await _hotSpotTypeRepository.Queryable().Where(x => x.ParentId == parentId).ToListAsync();
  230. }
  231. }