TestController.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. using System.Collections.Concurrent;
  2. using System.Data;
  3. using System.IO;
  4. using System.Threading;
  5. using DotNetCore.CAP;
  6. using Fw.Utility.Client;
  7. using Google.Protobuf.WellKnownTypes;
  8. using Hotline.Ai.Visit;
  9. using Hotline.Application.ExportExcel;
  10. using Hotline.CallCenter.BlackLists;
  11. using Hotline.CallCenter.Calls;
  12. using Hotline.CallCenter.Devices;
  13. using Hotline.CallCenter.Ivrs;
  14. using Hotline.FlowEngine.WorkflowModules;
  15. using Hotline.FlowEngine.Workflows;
  16. using Hotline.Identity.Roles;
  17. using Hotline.Import;
  18. using Hotline.Orders;
  19. using Hotline.Realtimes;
  20. using Hotline.Repository.SqlSugar;
  21. using Hotline.Repository.SqlSugar.System;
  22. using Hotline.Repository.SqlSugar.Ts;
  23. using Hotline.Settings;
  24. using Hotline.Settings.TimeLimits;
  25. using Hotline.Share.Dtos;
  26. using Hotline.Share.Dtos.FlowEngine;
  27. using Hotline.Share.Dtos.Order;
  28. using Hotline.Share.Dtos.Realtime;
  29. using Hotline.Share.Enums.Settings;
  30. using Hotline.Share.Mq;
  31. using Hotline.Tools;
  32. using Hotline.Users;
  33. using MapsterMapper;
  34. using MediatR;
  35. using Microsoft.AspNetCore.Authorization;
  36. using Microsoft.AspNetCore.Components.Routing;
  37. using Microsoft.AspNetCore.Http;
  38. using Microsoft.AspNetCore.Mvc;
  39. using Microsoft.AspNetCore.Routing.Template;
  40. using Microsoft.Extensions.Options;
  41. using MiniExcelLibs;
  42. using NewRock.Sdk;
  43. using NewRock.Sdk.Security;
  44. using SqlSugar;
  45. using SqlSugar.SplitTableExtensions;
  46. using Tr.Sdk;
  47. using XC.RSAUtil;
  48. using XF.Domain.Authentications;
  49. using XF.Domain.Cache;
  50. using XF.Domain.Entities;
  51. using XF.Domain.Exceptions;
  52. using XF.Domain.Filters;
  53. using XF.Domain.Locks;
  54. using XF.Domain.Queues;
  55. using XF.Domain.Repository;
  56. using XF.EasyCaching;
  57. namespace Hotline.Api.Controllers;
  58. /// <summary>
  59. ///
  60. /// </summary>
  61. [AllowAnonymous]
  62. public class TestController : BaseController
  63. {
  64. private readonly ILogger<TestController> _logger;
  65. private readonly IAuthorizeGenerator _authorizeGenerator;
  66. private readonly IOptionsSnapshot<CallCenterConfiguration> _options;
  67. private readonly ISessionContext _sessionContext;
  68. private readonly IRepository<User> _userRepository;
  69. private readonly ITypedCache<User> _cache;
  70. private readonly IRealtimeService _realtimeService;
  71. private readonly IBlacklistDomainService _blacklistDomainService;
  72. private readonly IIvrDomainService _ivrDomainService;
  73. private readonly ISugarUnitOfWork<HotlineDbContext> _uow;
  74. private readonly IRepository<Role> _roleRepository;
  75. private readonly IMediator _mediator;
  76. private readonly IDistributedLock _distributedLock;
  77. private readonly IRepository<OrderUrge> _orderUrgeRepository;
  78. private readonly IRepositoryTextSearch<OrderTs> _repositoryts;
  79. private readonly ITimeLimitDomainService _timeLimitDomainService;
  80. private readonly IWfModuleDomainService _wfModuleDomainService;
  81. private readonly IDaySettingRepository _daySettingRepository;
  82. private readonly ITrClient _trClient;
  83. private readonly ICapPublisher _capPublisher;
  84. private readonly IQueue _queue;
  85. private readonly IExportApplication _exportApplication;
  86. private readonly IAiVisitService _aiVisitService;
  87. private readonly IRepository<WorkflowTrace> _workflowTraceRepository;
  88. private readonly IRepository<WorkflowStepHandler> _workflowStepHandleRepository;
  89. private readonly IRepository<SystemOrganize> _systemOrganizeRepository;
  90. private readonly IMapper _mapper;
  91. //private readonly ITypedCache<List<User>> _cache;
  92. //private readonly ICacheManager<User> _cache;
  93. public TestController(
  94. INewRockClient client,
  95. ILogger<TestController> logger,
  96. IAuthorizeGenerator authorizeGenerator,
  97. IOptionsSnapshot<CallCenterConfiguration> options,
  98. ISessionContext sessionContext,
  99. IRepository<User> userRepository,
  100. //ICacheManager<User> cache
  101. //ITypedCache<List<User>> cache
  102. ITypedCache<User> cache,
  103. IRealtimeService realtimeService,
  104. IBlacklistDomainService blacklistDomainService,
  105. IIvrDomainService ivrDomainService,
  106. ISugarUnitOfWork<HotlineDbContext> uow,
  107. IRepository<Role> roleRepository,
  108. IMediator mediator,
  109. IDistributedLock distributedLock,
  110. IRepository<OrderUrge> orderUrgeRepository,
  111. IRepositoryTextSearch<OrderTs> repositoryts,
  112. ITimeLimitDomainService timeLimitDomainService,
  113. IWfModuleDomainService wfModuleDomainService,
  114. IDaySettingRepository daySettingRepository,
  115. ITrClient trClient,
  116. ICapPublisher capPublisher,
  117. IQueue queue,
  118. IExportApplication exportApplication,
  119. IAiVisitService aiVisitService,
  120. IRepository<WorkflowTrace> workflowTraceRepository,
  121. IRepository<WorkflowStepHandler> workflowStepHandleRepository,
  122. IRepository<SystemOrganize> systemOrganizeRepository,
  123. IMapper mapper
  124. )
  125. {
  126. _logger = logger;
  127. _authorizeGenerator = authorizeGenerator;
  128. _options = options;
  129. _sessionContext = sessionContext;
  130. _userRepository = userRepository;
  131. _cache = cache;
  132. _realtimeService = realtimeService;
  133. _blacklistDomainService = blacklistDomainService;
  134. _ivrDomainService = ivrDomainService;
  135. _uow = uow;
  136. _roleRepository = roleRepository;
  137. _mediator = mediator;
  138. _distributedLock = distributedLock;
  139. _orderUrgeRepository = orderUrgeRepository;
  140. _repositoryts = repositoryts;
  141. _timeLimitDomainService = timeLimitDomainService;
  142. _wfModuleDomainService = wfModuleDomainService;
  143. _daySettingRepository = daySettingRepository;
  144. _trClient = trClient;
  145. _capPublisher = capPublisher;
  146. _queue = queue;
  147. _exportApplication = exportApplication;
  148. _aiVisitService = aiVisitService;
  149. _workflowTraceRepository = workflowTraceRepository;
  150. _workflowStepHandleRepository = workflowStepHandleRepository;
  151. _systemOrganizeRepository = systemOrganizeRepository;
  152. _mapper = mapper;
  153. }
  154. [HttpGet("testo")]
  155. public async Task<OpenResponse> TestOrigin()
  156. {
  157. var now = DateTime.Now.ToString();
  158. return OpenResponse.Ok(now);
  159. }
  160. [HttpGet("init-orgname")]
  161. [AllowAnonymous]
  162. public async Task InitUserOrgFullName()
  163. {
  164. var list = await _userRepository.Queryable().Where(x => 1 == 1 && string.IsNullOrEmpty(x.FullOrgName)).ToListAsync();
  165. foreach (var item in list)
  166. {
  167. var orgFullName = "";
  168. var orgFullCode = "";
  169. var orgId = item.OrgId;
  170. int strLength = orgId.Length;
  171. int segmentsCount = strLength / 3;
  172. List<string> strings = new List<string>();
  173. for (int i = 0; i < segmentsCount; i++)
  174. {
  175. int startIndex = i * 3;
  176. int length = Math.Min(3, strLength - startIndex);
  177. strings.Add(orgId.Substring(startIndex, length));
  178. }
  179. if (strLength > 3)
  180. {
  181. orgFullCode = strings[0];
  182. strings.Remove(orgFullCode);
  183. }
  184. foreach (var str in strings)
  185. {
  186. orgFullCode = orgFullCode + str;
  187. var org = await _systemOrganizeRepository.GetAsync(orgFullCode);
  188. if (org != null)
  189. {
  190. orgFullName = orgFullName + org.Name + "/";
  191. }
  192. }
  193. if (orgFullName.Length > 0)
  194. {
  195. orgFullName = orgFullName.Remove(orgFullName.Length - 1);
  196. }
  197. item.FullOrgName = orgFullName;
  198. await _userRepository.UpdateAsync(item);
  199. }
  200. }
  201. [HttpPost("import")]
  202. [AllowAnonymous]
  203. public async Task<List<ExcelContent>> Import(IFormFile file)
  204. {
  205. //var FileName = file.FileName;
  206. //var fileExtension = Path.GetExtension(FileName);
  207. ////新文件名
  208. //var newFileName = DateTime.Now.ToString("yyyyMMddhhmmss");
  209. ////文件保存路径
  210. //var filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "Upload", newFileName);
  211. ////判断路径是否存在
  212. //if (!Directory.Exists(filePath))
  213. //{
  214. // //创建路径
  215. // Directory.CreateDirectory(filePath);
  216. //}
  217. //filePath = Path.Combine(filePath, newFileName+ fileExtension);
  218. using (var stream = new MemoryStream())
  219. {
  220. file.CopyTo(stream);
  221. var list = MiniExcel.Query<ExcelContent>(stream).ToList();
  222. //Directory.Delete(filePath, true);
  223. return list;
  224. }
  225. }
  226. [AllowAnonymous]
  227. [HttpGet("export")]
  228. public async Task<object> Export()
  229. {
  230. List<ExcelContent> list = new List<ExcelContent>();
  231. ExcelContent excelContent = new ExcelContent() { ExternalId = "123123" };
  232. list.Add(excelContent);
  233. return _exportApplication.ExportData<ExcelContent>(list, "demo.xlsx");
  234. }
  235. [HttpGet("time")]
  236. [AllowAnonymous]
  237. public async Task<OpenResponse> GetTime(string batchId, string taskId)
  238. {
  239. //await _repositoryts.AddVectorAsync("f595e730-909a-45e4-9138-a84bf15f4662", DateTime.Now,
  240. // new List<string> { "xx", "bb" }, HttpContext.RequestAborted);
  241. //var result = await _repositoryts.SearchAsync(new List<string> { "bb" }, HttpContext.RequestAborted);
  242. //await _repositoryts.UpdateVectorAsync("f595e730-909a-45e4-9138-a84bf15f4662",
  243. // new List<string> { "ss", "bb" }, HttpContext.RequestAborted);
  244. //_uow.Db.Ado.SqlQueryAsync<OrderUrge>("SELECT to_tsvector('fat cats ate fat rats') @@ to_tsquery('fat & rat')")
  245. //var tests = _uowWex.Db.Ado.SqlQuery<Test>("select * from view_telinfo_full where IsSynch=@IsSynch", new { IsSynch = 0 });
  246. //var a = _uowWex.Db.Ado.ExecuteCommand("update telinfo set IsSynch=1 where GUID=@CallId", new { CallId = "b1f97f3c-88b6-4f42-b8de-83ed448854b0" });
  247. //var rsp = await _wexClient.QueryTelsAsync(new QueryTelRequest { }, HttpContext.RequestAborted);
  248. //int a = _timeLimitDomainService.CalcWorkTime(DateTime.Now, DateTime.Parse("2023-09-11 16:21:00"));
  249. //int m = _timeLimitDomainService.CalcWorkTime(DateTime.Parse("2023-09-19 12:00:00"), DateTime.Parse("2023-09-20 18:00:00"), false);
  250. //var r = _timeLimitDomainService.CalcEndTime(DateTime.Parse("2024-03-07 14:09:45"), ETimeType.WorkDay,1,false,80);
  251. //var r = _timeLimitDomainService.CalcExpiredTime(DateTime.Parse("2024-02-29 10:12:33"), Share.Enums.FlowEngine.EFlowDirection.OrgToCenter, "10");
  252. //await _wfModuleDomainService.PersistenceModulesAsync(HttpContext.RequestAborted);
  253. //var rsp = await _daprClient.InvokeMethodAsync<ApiResponse<string>>(HttpMethod.Get, "identity", "api/v1/Test/time", HttpContext.RequestAborted);
  254. //var rsp1 = await _daprClient.InvokeMethodAsync<int, ApiResponse<string>>(HttpMethod.Post, "identity", "api/v1/Test/time1", 222, HttpContext.RequestAborted);
  255. //var a = await _trClient.QueryTelsAsync(new Tr.Sdk.Tels.QueryTelRequest() { }, HttpContext.RequestAborted);
  256. //await _daySettingRepository.IsWorkDay(DateTime.Now);
  257. //var r = _timeLimitDomainService.CalcWorkTime(DateTime.Parse("2024-3-22 05:00:00"), DateTime.Parse("2024-3-22 06:00:00"), false);
  258. //var r = _timeLimitDomainService.CalcWorkTime(DateTime.Parse("2024-3-24 17:20:00"), DateTime.Parse("2024-3-24 17:21:00"), false);
  259. //await _aiVisitService.QueryAiVisitTask(batchId, taskId, HttpContext.RequestAborted);
  260. //var r = _timeLimitDomainService.CalcWorkTimeReduce(DateTime.Now, 5);
  261. var r = _timeLimitDomainService.CalcWorkTimeToDecimal(DateTime.Parse("2024-05-14 14:41:42"), DateTime.Parse("2024-05-14 14:50:46"), false);
  262. return OpenResponse.Ok(DateTime.Now.ToString("F"));
  263. }
  264. [HttpGet("pgsql")]
  265. public async Task<string> Pgsql()
  266. {
  267. var role = new Role
  268. {
  269. Name = $"test_role_{TimeOnly.FromDateTime(DateTime.Now)}",
  270. DisplayName = "test_role_display",
  271. ClientId = "test"
  272. };
  273. var roleId = await _roleRepository.AddAsync(role, HttpContext.RequestAborted);
  274. role.Description = "Description";
  275. await _roleRepository.UpdateAsync(role, HttpContext.RequestAborted);
  276. return roleId;
  277. }
  278. [AllowAnonymous]
  279. [HttpGet("roles")]
  280. public async Task<List<Role>> GetRoles()
  281. {
  282. using var lockManager = new LockManager(_distributedLock, $"{nameof(TestController)}.{nameof(GetRoles)}");
  283. lockManager.InvokeInLock(() => { Console.WriteLine("do something"); }, TimeSpan.FromSeconds(10));
  284. await lockManager.InvokeInLockAsync(
  285. d => _roleRepository.Queryable(includeDeleted: true).ToListAsync(),
  286. TimeSpan.FromSeconds(10),
  287. HttpContext.RequestAborted);
  288. var a = await _roleRepository.Queryable()
  289. //.Where(d => !d.IsDeleted)
  290. .ToListAsync();
  291. //var a = await db.Queryable<Role>().ToListAsync();
  292. var b = await _roleRepository.Queryable(includeDeleted: true).ToListAsync();
  293. return a;
  294. }
  295. //[AllowAnonymous]
  296. [HttpGet("hash")]
  297. public async Task Hash()
  298. {
  299. var s = _sessionContext;
  300. }
  301. /// <summary>
  302. /// signalR测试(method: Ring)
  303. /// </summary>
  304. /// <returns></returns>
  305. [HttpGet("ring")]
  306. public async Task RingTest()
  307. {
  308. await _realtimeService.RingAsync(_sessionContext.RequiredUserId,
  309. new RingDto { Id = new Guid().ToString(), From = _sessionContext.Phone ?? "未知号码", To = "12345" },
  310. HttpContext.RequestAborted);
  311. }
  312. /// <summary>
  313. /// signalR测试(method: Answered)
  314. /// </summary>
  315. /// <returns></returns>
  316. [HttpGet("answered")]
  317. public async Task AnsweredTest()
  318. {
  319. await _realtimeService.AnsweredAsync(_sessionContext.RequiredUserId,
  320. new AnsweredDto() { Id = new Guid().ToString(), From = _sessionContext.Phone ?? "未知号码", To = "12345" },
  321. HttpContext.RequestAborted);
  322. }
  323. /// <summary>
  324. /// signalR测试(method: Bye)
  325. /// </summary>
  326. /// <returns></returns>
  327. [HttpGet("bye")]
  328. public async Task ByeTest()
  329. {
  330. await _realtimeService.ByeAsync(_sessionContext.RequiredUserId, new ByeDto() { Id = new Guid().ToString() },
  331. HttpContext.RequestAborted);
  332. }
  333. /// <summary>
  334. ///
  335. /// </summary>
  336. /// <returns></returns>
  337. [AllowAnonymous]
  338. [HttpGet("t2")]
  339. public async Task GetVoiceEndAnswerAsyncTest()
  340. {
  341. //var answer = await _ivrDomainService.GetVoiceEndAnswerAsync("3", HttpContext.RequestAborted);
  342. //Console.WriteLine(answer.Content);
  343. throw new UserFriendlyException(2001, "test");
  344. }
  345. [HttpGet("wfdefine")]
  346. public async Task GetWorkflowDefine([FromQuery] string id)
  347. {
  348. //var query = _workflowTraceRepository.Queryable()
  349. // .LeftJoin<Workflow>((t, w) => t.WorkflowId == w.Id)
  350. // .LeftJoin<Order>((t, w, o) => w.ExternalId == o.Id)
  351. // .Where((t, w, o) => o.No.Length == 14);
  352. //if (!string.IsNullOrEmpty(id))
  353. // query = query.Where(d => d.WorkflowId == id);
  354. //var list = await query
  355. // .Select((t, w, o) => new { t, w, o })
  356. // .ToListAsync(HttpContext.RequestAborted);
  357. //var toUsers = list.Where(d => d.t.FlowAssignType == EFlowAssignType.User).ToList();
  358. //var userIds = toUsers.SelectMany(d => d.t.Handlers).Select(d => d.Key).Distinct().ToList();
  359. //var users = await _userRepository.Queryable()
  360. // .Includes(d => d.Organization)
  361. // .Where(d => userIds.Contains(d.Id))
  362. // .ToListAsync(HttpContext.RequestAborted);
  363. ////var orgTraces = list.Where(d => d.FlowAssignType == EFlowAssignType.Org).ToList();
  364. //var stepHandlers = new List<WorkflowStepHandler>();
  365. //foreach (var toUser in toUsers)
  366. //{
  367. // foreach (var traceHandler in toUser.t.Handlers)
  368. // {
  369. // var user = users.FirstOrDefault(d => d.Id == traceHandler.Key);
  370. // if (user != null)
  371. // stepHandlers.Add(new WorkflowStepHandler
  372. // {
  373. // WorkflowId = toUser.w.Id,
  374. // ExternalId = toUser.w.ExternalId,
  375. // WorkflowStepId = toUser.t.StepId,
  376. // FlowAssignType = toUser.t.FlowAssignType.Value,
  377. // UserId = user.Id,
  378. // Username = user.Name,
  379. // OrgId = user.OrgId,
  380. // OrgName = user.Organization.Name,
  381. // IsActualHandler = user.Id == toUser.t.HandlerId
  382. // });
  383. // }
  384. //}
  385. //var toOrgs = list.Where(d => d.t.FlowAssignType == EFlowAssignType.Org).ToList();
  386. //foreach (var toOrg in toOrgs)
  387. //{
  388. // foreach (var handler in toOrg.t.Handlers)
  389. // {
  390. // stepHandlers.Add(new WorkflowStepHandler
  391. // {
  392. // WorkflowId = toOrg.w.Id,
  393. // ExternalId = toOrg.w.ExternalId,
  394. // WorkflowStepId = toOrg.t.StepId,
  395. // FlowAssignType = toOrg.t.FlowAssignType.Value,
  396. // OrgId = handler.Key,
  397. // OrgName = handler.Value,
  398. // IsActualHandler = handler.Key == toOrg.t.HandlerOrgId
  399. // });
  400. // }
  401. //}
  402. //_logger.LogInformation($"生成handlers: {stepHandlers.Count} 条");
  403. //await _workflowStepHandleRepository.AddRangeAsync(stepHandlers, HttpContext.RequestAborted);
  404. }
  405. [AllowAnonymous]
  406. [HttpPost("t3")]
  407. public async Task TestExportExcel()
  408. {
  409. }
  410. [HttpGet("rsa")]
  411. public async Task<string> Rsa()
  412. {
  413. var keyList = RsaKeyGenerator.Pkcs1Key(2048, true);
  414. var privateKey = keyList[0];
  415. var publicKey = keyList[1];
  416. return $"{publicKey} \r\n {privateKey}";
  417. }
  418. }