郑州市第一人民医院

DistriWorkOrderPlanController.cs 70KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using Microsoft.AspNetCore.Mvc;
  6. using MadRunFabric.Common;
  7. using Microsoft.AspNetCore.Authorization;
  8. using Microsoft.Extensions.Logging;
  9. using DistributionApi.IRepositories;
  10. using Api.SignToken;
  11. using System.Security.Claims;
  12. using DistributionApi.Models.Input;
  13. using MadRunFabric.Model;
  14. using MongoDB.Bson;
  15. using System.Threading;
  16. using MadRunFabric.Model.MessageApi;
  17. using Microsoft.Extensions.Configuration;
  18. namespace DistributionApi.Controllers
  19. {
  20. /// <summary>
  21. /// 配送计划 - 省三院
  22. /// </summary>
  23. [Authorize]
  24. [ApiVersion("6.0")]
  25. [Route("api/[controller]")]
  26. [Produces("application/json")]
  27. public class DistriWorkOrderPlanController : BaseController
  28. {
  29. private readonly ILogger<DistriWorkOrderPlanController> _logger;
  30. private readonly IConfiguration _configuration;
  31. private readonly ISys_User_AccountRepository _sys_user_accountRepository;
  32. private readonly ISignTokenService _signTokenService;
  33. private readonly IDistri_Workorder_PlanRepository _distri_workorder_planrepository;
  34. private readonly IDistri_Workorder_PlanTaskRepository _distri_workorder_plantaskrepository;
  35. private readonly IDistri_WorkorderRepository _distri_workorderrepository;
  36. private readonly IDistri_Workorder_ItemsRepository _distri_workorder_itemsrepository;
  37. private readonly IDistri_Workorder_EvaluateRepository _distri_workorder_evaluaterepository;
  38. private readonly IPro_Project_InfoRepository _pro_project_infoRepository;
  39. private readonly IHangfirePlan_DistributionRepository _hangfireplan_distributionrepository;
  40. private readonly IHangfireService _hangfireService;
  41. private readonly IWechatService _wechatservice;
  42. private readonly ISys_ClassGroupRepository _sys_classgrouprepository;
  43. private readonly ISys_ClassGroup_User_MapRepository _sys_classgroup_user_maprepository;
  44. private readonly ISys_User_AccountRepository _sys_user_accountrepository;
  45. private readonly ISys_Role_InfoRepository _sys_role_inforepository;
  46. private readonly IWo_Order_User_MapRepository _wo_order_user_maprepository;
  47. private readonly ISys_User_AccountRepository _distri_sys_user_accountrepository;
  48. public DistriWorkOrderPlanController(
  49. ILogger<DistriWorkOrderPlanController> logger,
  50. IConfiguration configuration,
  51. ISys_User_AccountRepository sys_user_accountRepository,
  52. ISignTokenService signTokenService,
  53. IDistri_Workorder_PlanRepository distri_workorder_planrepository,
  54. IDistri_Workorder_PlanTaskRepository distri_workorder_plantaskrepository,
  55. IDistri_WorkorderRepository distri_workorderrepository,
  56. IDistri_Workorder_ItemsRepository distri_workorder_itemsrepository,
  57. IDistri_Workorder_EvaluateRepository distri_workorder_evaluaterepository,
  58. IPro_Project_InfoRepository pro_project_infoRepository,
  59. IHangfirePlan_DistributionRepository hangfireplan_distributionrepository,
  60. IHangfireService hangfireService,
  61. IWechatService wechatservice,
  62. ISys_ClassGroupRepository sys_classgrouprepository,
  63. ISys_ClassGroup_User_MapRepository sys_classgroup_user_maprepository,
  64. ISys_User_AccountRepository sys_user_accountrepository,
  65. ISys_Role_InfoRepository sys_role_inforepository,
  66. IWo_Order_User_MapRepository wo_order_user_maprepository,
  67. ISys_User_AccountRepository distri_sys_user_accountrepository
  68. )
  69. {
  70. _logger = logger;
  71. _configuration = configuration;
  72. _sys_user_accountRepository = sys_user_accountRepository;
  73. _signTokenService = signTokenService;
  74. _distri_workorder_planrepository = distri_workorder_planrepository;
  75. _distri_workorder_plantaskrepository = distri_workorder_plantaskrepository;
  76. _distri_workorderrepository = distri_workorderrepository;
  77. _distri_workorder_itemsrepository = distri_workorder_itemsrepository;
  78. _distri_workorder_evaluaterepository = distri_workorder_evaluaterepository;
  79. _pro_project_infoRepository = pro_project_infoRepository;
  80. _hangfireplan_distributionrepository = hangfireplan_distributionrepository;
  81. _hangfireService = hangfireService;
  82. _wechatservice = wechatservice;
  83. _sys_classgrouprepository = sys_classgrouprepository;
  84. _sys_classgroup_user_maprepository = sys_classgroup_user_maprepository;
  85. _sys_user_accountrepository = sys_user_accountrepository;
  86. _sys_role_inforepository = sys_role_inforepository;
  87. _wo_order_user_maprepository = wo_order_user_maprepository;
  88. _distri_sys_user_accountrepository = distri_sys_user_accountrepository;
  89. }
  90. #region 计划管理
  91. /// <summary>
  92. /// 获取配送计划列表分页 by page
  93. /// </summary>
  94. /// <param name="keyword"></param>
  95. /// <param name="stime"></param>
  96. /// <param name="etime"></param>
  97. /// <param name="pageindex"></param>
  98. /// <param name="pagesize"></param>
  99. /// <returns></returns>
  100. [HttpGet("getlistbypage")]
  101. public async Task<IActionResult> GetListByPageAsync(string keyword, string projectid, int planstate = -1, int pageindex = 1, int pagesize = 10)
  102. {
  103. string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
  104. //var userstr = _signTokenService.GetUserInfoAsync(usercode).Result;
  105. //var userinfo = userstr.ToJObject()["data"].ToString().ToObject<UserInfoModel>();
  106. string allprojectrole = _configuration["allprojectrole"];
  107. var userinfos = _sys_user_accountRepository.GetUserInfo(usercode, allprojectrole);
  108. var userinfo = JsonHelper.JsonToEntity<UserAccountInfoModel>(userinfos.ToJson());
  109. //获取数据
  110. int recordCount = 0;
  111. var result = _distri_workorder_planrepository.GetListsByPage(keyword, projectid, planstate, userinfo, pageindex, pagesize, out recordCount);
  112. var list = result.ToList();
  113. //获取所有 HangFirePlan 关系图
  114. var listHangFirePlan = await _hangfireplan_distributionrepository.GetAll();
  115. foreach (var item in list)
  116. {
  117. if (!string.IsNullOrWhiteSpace(item.hangfireid))
  118. {
  119. var hfmo = listHangFirePlan.FirstOrDefault(x=>x.id == item.hangfireid);
  120. if (hfmo != null)
  121. {
  122. item.plancycle = hfmo.plancycle;
  123. item.planinterval = hfmo.planinterval;
  124. item.plantimes = hfmo.plantimes;
  125. item.extensiontime = hfmo.extensiontime;
  126. }
  127. }
  128. }
  129. var obj = new
  130. {
  131. rows = list.ToList(),
  132. total = recordCount
  133. };
  134. return Success("获取成功", obj);
  135. }
  136. /// <summary>
  137. /// 获取配送计划详情
  138. /// </summary>
  139. [HttpGet("getsingle")]
  140. public async Task<IActionResult> GetSingleAsync(string id)
  141. {
  142. if (string.IsNullOrEmpty(id))
  143. return Error("参数错误");
  144. var model = _distri_workorder_planrepository.GetDetails(id);
  145. if (model != null)
  146. {
  147. if (!string.IsNullOrWhiteSpace(model.hangfireid))
  148. {
  149. var hfmo = await _hangfireplan_distributionrepository.GetSingle(model.hangfireid);
  150. if (hfmo != null)
  151. {
  152. model.plancycle = hfmo.plancycle;
  153. model.planinterval = hfmo.planinterval;
  154. model.plantimes = hfmo.plantimes;
  155. model.extensiontime = hfmo.extensiontime;
  156. }
  157. }
  158. return Success("获取成功!", model);
  159. }
  160. return Success("获取成功", model);
  161. }
  162. /// <summary>
  163. /// 添加配送计划
  164. /// </summary>
  165. [HttpPost("add")]
  166. public async Task<IActionResult> AddAsync(DistriWorkOrderPlanInput input)
  167. {
  168. string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
  169. string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;
  170. if (string.IsNullOrWhiteSpace(input.projectid))
  171. return Error("请选择项目");
  172. var pro = await _pro_project_infoRepository.GetSingle(input.projectid);
  173. if (pro != null && pro.isend == 1)
  174. return Error("该项目已暂停");
  175. #region 判断验证
  176. if (string.IsNullOrEmpty(input.projectid))
  177. return Error("请选择项目");
  178. if (string.IsNullOrEmpty(input.planname))
  179. return Error("请选择计划名称");
  180. if (input.goodslist == null || input.goodslist.Count <= 0)
  181. return Error("请选择物品种类");
  182. int goodsnum = input.goodslist.Sum(x => x.num);
  183. if (goodsnum <= 0)
  184. return Error("请填写物品数量");
  185. if (input.deliverylist == null || input.deliverylist.Count <= 0)
  186. return Error("请选择发货地址");
  187. #endregion
  188. var model = new Distri_Workorder_Plan();
  189. #region model 添加配送计划对象
  190. model.projectid = input.projectid;
  191. model.channel = input.channel;
  192. model.planname = input.planname;
  193. model.plancontent = input.plancontent;
  194. //model.planstate = input.planstate;
  195. model.startdate = input.startdate;
  196. model.enddate = input.enddate;
  197. model.createtby = usercode;
  198. model.goodslist = input.goodslist;
  199. model.deliverylist = input.deliverylist;
  200. model.deliveryname = input.deliveryname;
  201. model.deliverytel = input.deliverytel;
  202. #endregion
  203. bool b = await _distri_workorder_planrepository.Add(model);
  204. if (b)
  205. {
  206. #region 添加定时计划任务
  207. //保存计划任务 - 方法
  208. var planid = await addDistributionPlan(input, "");
  209. model.hangfireid = planid;
  210. await _distri_workorder_planrepository.UpdateOne(model);
  211. //_logger.LogError(null, "ceshi2:" + input.ToJson());
  212. //设置定时任务
  213. var extensiontime = JsonHelper.ObjectToJson(input.extensiontime);
  214. SetTaskAsync(model.id, input.plancycle, input.planinterval, input.plantimes, extensiontime);
  215. #endregion
  216. //if (DateTime.Now.Date == input.startdate.Date)
  217. //{
  218. // await AddHangfirePlanWorkorderAsync(model);
  219. //}
  220. return Success("保存成功");
  221. }
  222. else
  223. return Error("保存失败");
  224. }
  225. /// <summary>
  226. /// 修改配送计划
  227. /// </summary>
  228. [HttpPost("update")]
  229. public async Task<IActionResult> UpdateAsync(DistriWorkOrderPlanInput input)
  230. {
  231. string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
  232. string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;
  233. if (string.IsNullOrWhiteSpace(input.projectid))
  234. return Error("请选择项目");
  235. var pro = await _pro_project_infoRepository.GetSingle(input.projectid);
  236. if (pro != null && pro.isend == 1)
  237. return Error("该项目已暂停");
  238. var model = await _distri_workorder_planrepository.GetSingle(p => p.id == input.id);
  239. if (model != null)
  240. {
  241. #region 判断验证
  242. if (string.IsNullOrEmpty(input.projectid))
  243. return Error("请选择项目");
  244. if (string.IsNullOrEmpty(input.planname))
  245. return Error("请选择计划名称");
  246. if (input.goodslist == null || input.goodslist.Count <= 0)
  247. return Error("请选择物品种类");
  248. int goodsnum = input.goodslist.Sum(x => x.num);
  249. if (goodsnum <= 0)
  250. return Error("请填写物品数量");
  251. if (input.deliverylist == null || input.deliverylist.Count <= 0)
  252. return Error("请选择发货地址");
  253. #endregion
  254. #region model 添加配送计划对象
  255. model.projectid = input.projectid;
  256. model.channel = input.channel;
  257. model.planname = input.planname;
  258. model.plancontent = input.plancontent;
  259. model.planstate = input.planstate;
  260. model.startdate = input.startdate;
  261. model.enddate = input.enddate;
  262. model.createtby = usercode;
  263. model.goodslist = input.goodslist;
  264. model.deliverylist = input.deliverylist;
  265. model.deliveryname = input.deliveryname;
  266. model.deliverytel = input.deliverytel;
  267. #endregion
  268. bool b = await _distri_workorder_planrepository.UpdateOne(model);
  269. if (b)
  270. {
  271. #region 添加定时计划任务
  272. //保存计划任务 - 方法
  273. var planid = await addDistributionPlan(input, "");
  274. model.hangfireid = planid;
  275. await _distri_workorder_planrepository.UpdateOne(model);
  276. //设置定时任务
  277. var extensiontime = JsonHelper.ObjectToJson(input.extensiontime);
  278. SetTaskAsync(model.id, input.plancycle, input.planinterval, input.plantimes, extensiontime);
  279. //_logger.LogError(null, "ceshi2:" + input.ToJson());
  280. #endregion
  281. return Success("保存成功");
  282. }
  283. else
  284. return Error("保存失败");
  285. }
  286. return Error("参数错误");
  287. }
  288. #region 不用的
  289. ///// <summary>
  290. ///// 完成计划 - 只是此计划完成,与循环无关
  291. ///// </summary>
  292. ///// <param name="id"></param>
  293. ///// <param name="channel"></param>
  294. ///// <returns></returns>
  295. //[HttpPost("finish")]
  296. //public async Task<IActionResult> UpdateFinishAsync(string id)
  297. //{
  298. // string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
  299. // if (string.IsNullOrEmpty(id))
  300. // return Error("参数错误");
  301. // var model = await _distri_workorder_planrepository.GetSingle(id);
  302. // if (model == null)
  303. // return Error("操作失败");
  304. // if (model.planstate == (int)EnumDistriWorkOrderPlanstate.finish)
  305. // return Error("操作失败,计划已完成");
  306. // model.dealby = usercode; //处理人
  307. // model.dealtime = DateTime.Now; //处理时间
  308. // //配送计划状态:0创建计划,1已完成
  309. // model.planstate = (int)EnumDistriWorkOrderPlanstate.finish;
  310. // bool b = await _distri_workorder_planrepository.UpdateOne(model);
  311. // if (b)
  312. // {
  313. // return Success("接单成功");
  314. // }
  315. // return Error("接单失败");
  316. //}
  317. #endregion
  318. /// <summary>
  319. /// 删除配送计划
  320. /// </summary>
  321. /// <param name="ids"></param>
  322. /// <returns></returns>
  323. [HttpPost("delete")]
  324. public async Task<IActionResult> RemoveAsync(string[] ids)
  325. {
  326. string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
  327. //使用逻辑删除
  328. //物理删除的数据无法恢复
  329. var res = 0;
  330. if (ids == null && ids.Length <= 0)
  331. return Error("请选择要删除的记录");
  332. foreach (var item in ids)
  333. {
  334. var model_Plan = await _distri_workorder_planrepository.GetSingle(item);
  335. model_Plan.isdelete = 1;
  336. model_Plan.deleteby = usercode;
  337. model_Plan.deletetime = DateTime.Now;
  338. if (await _distri_workorder_planrepository.UpdateOne(model_Plan))
  339. {
  340. #region 查询此计划是否有未执行的工单,若有一并删除
  341. var list_Wo = await _distri_workorderrepository.Get(r => r.planid.Equals(item) && r.wostate == (int)EnumEquipmentRunningState.create);
  342. if (list_Wo.Count() > 0)
  343. {
  344. foreach (var item_Dis in list_Wo)
  345. {
  346. item_Dis.isdelete = 1;
  347. item_Dis.deleteby = usercode;
  348. item_Dis.dealtime = DateTime.Now;
  349. await _distri_workorderrepository.UpdateOne(item_Dis);
  350. }
  351. }
  352. #endregion
  353. RemoveTask(model_Plan.id);
  354. res += 1;
  355. }
  356. }
  357. if (res == ids.Length)
  358. return Success("删除成功");
  359. else if (res > 0 && res < ids.Length)
  360. return Error("部分删除失败,请查看后重新操作");
  361. else
  362. return Error("删除失败,请查看后重新操作");
  363. }
  364. /// <summary>
  365. /// 启动计划
  366. /// </summary>
  367. /// <param name="ids"></param>
  368. /// <returns></returns>
  369. [HttpPost("start")]
  370. public async Task<IActionResult> StartAsync(string[] ids)
  371. {
  372. var res = 0;
  373. if (ids != null && ids.Length > 0)
  374. {
  375. try
  376. {
  377. foreach (var item in ids)
  378. {
  379. var ml = await _distri_workorder_planrepository.GetSingle(item);
  380. ml.planstate = 0;
  381. if (await _distri_workorder_planrepository.UpdateOne(ml))
  382. {
  383. var hl = await _hangfireplan_distributionrepository.GetSingle(ml.hangfireid);
  384. var extensiontime = JsonHelper.ObjectToJson(hl.extensiontime);
  385. SetTaskAsync(item, hl.plancycle, hl.planinterval, hl.plantimes, extensiontime);
  386. res += 1;
  387. }
  388. }
  389. if (res == ids.Length)
  390. return Success("操作成功");
  391. else if (res > 0 && res < ids.Length)
  392. return Error("部分操作失败,请查看后重新操作");
  393. else
  394. return Error("操作失败,请查看后重新操作");
  395. }
  396. catch (Exception ex)
  397. {
  398. _logger.LogError(ex, "启动计划异常");
  399. return Error("启动计划失败");
  400. }
  401. }
  402. else
  403. return Error("请选择要操作的记录");
  404. }
  405. /// <summary>
  406. /// 中止计划
  407. /// </summary>
  408. /// <param name="ids"></param>
  409. /// <returns></returns>
  410. [HttpPost("stop")]
  411. public async Task<IActionResult> StopAsync(string[] ids)
  412. {
  413. var res = 0;
  414. if (ids != null && ids.Length > 0)
  415. {
  416. try
  417. {
  418. foreach (var item in ids)
  419. {
  420. var ml = await _distri_workorder_planrepository.GetSingle(item);
  421. ml.planstate = 1;
  422. if (await _distri_workorder_planrepository.UpdateOne(ml))
  423. {
  424. RemoveTask(ml.id);
  425. res += 1;
  426. }
  427. }
  428. if (res == ids.Length)
  429. return Success("操作成功");
  430. else if (res > 0 && res < ids.Length)
  431. return Error("部分操作失败,请查看后重新操作");
  432. else
  433. return Error("操作失败,请查看后重新操作");
  434. }
  435. catch (Exception ex)
  436. {
  437. _logger.LogError(ex, "中止计划异常");
  438. return Error("中止计划失败");
  439. }
  440. }
  441. else
  442. return Error("请选择要操作的记录");
  443. }
  444. #endregion
  445. #region 方法 - 设置定时计划
  446. /// <summary>
  447. /// 设置定时任务
  448. /// </summary>
  449. /// <param name="id"></param>
  450. /// <param name="plancycle"></param>
  451. /// <param name="planinterval"></param>
  452. /// <param name="plantimes"></param>
  453. private void SetTaskAsync(string planid, int plancycle, int planinterval, int plantimes,string extensiontime)
  454. {
  455. _logger.LogDebug("DistriWorkOrderPlanController/SetTask start ");
  456. _hangfireService.AddDistriWorkOrderPlan(planid, plancycle, planinterval, plantimes, extensiontime);
  457. }
  458. /// <summary>
  459. /// 删除计划 - 到期删除
  460. /// </summary>
  461. /// <param name="id"></param>
  462. private void RemoveTask(string id)
  463. {
  464. _logger.LogDebug("DistriWorkOrderPlanController/RemoveTask remove");
  465. _hangfireService.RemoveDistriWorkOrderPlan(id);
  466. }
  467. #endregion
  468. #region 方法 - 保存计划任务定时
  469. /// <summary>
  470. /// 保存计划任务定时 - 方法
  471. /// </summary>
  472. /// <param name="input"></param>
  473. /// <param name="planid"></param>
  474. /// <returns></returns>
  475. private async Task<string> addDistributionPlan(DistriWorkOrderPlanInput input, string planid)
  476. {
  477. string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
  478. var model = new HangfirePlan_Distribution();
  479. if (!string.IsNullOrWhiteSpace(planid))
  480. {
  481. model = await _hangfireplan_distributionrepository.GetSingle(planid);
  482. }
  483. else
  484. {
  485. model.id = ObjectId.GenerateNewId().ToString();
  486. model.wotype = (int)EnumDistributionWoType.distribution;
  487. model.createby = usercode;
  488. model.createtime = DateTime.Now;
  489. model.isdelete = 0;
  490. //bool b = await _hangfireplan_distributionepository.Add(model);
  491. }
  492. model.plantype = 1; //定时计划
  493. model.plancycle = input.plancycle;
  494. model.plantimes = input.plantimes;
  495. model.planinterval = input.planinterval;
  496. model.planstate = input.planstate;
  497. model.extensiontime = input.extensiontime;
  498. var b = false;
  499. if (string.IsNullOrWhiteSpace(planid))
  500. b = await _hangfireplan_distributionrepository.Add(model);
  501. else
  502. b = await _hangfireplan_distributionrepository.UpdateOne(model);
  503. if (b)
  504. return model.id;
  505. else
  506. return "";
  507. }
  508. #endregion
  509. #region 添加计划工单 - Hangfire循环定时 - 为Hangfire提供接口
  510. /// <summary>
  511. /// 添加计划工单 - Hangfire循环定时
  512. /// </summary>
  513. [AllowAnonymous]
  514. [HttpPost("addhangfire")]
  515. public async Task<IActionResult> AddHangfireAsync(string planid)
  516. {
  517. _logger.LogDebug("DistriWorkOrderPlanController/AddHangfireAsync 添加计划工单 start");
  518. if (string.IsNullOrWhiteSpace(planid))
  519. {
  520. _logger.LogError("AddHangfireAsync Error 计划不能为空");
  521. return Error("计划不能为空");
  522. }
  523. var b = false;
  524. //获取上一计划详情,作为生成模板
  525. var modelPlan = await _distri_workorder_planrepository.GetSingle(planid);
  526. if (modelPlan != null)
  527. {
  528. if (DateTime.Now.Date < modelPlan.startdate.Date)
  529. {
  530. _logger.LogDebug("AddHangfireAsync Error 未到计划执行时间,计划名称:" + modelPlan.planname);
  531. return Error("未到计划执行时间");
  532. }
  533. if (DateTime.Now.Date > modelPlan.enddate.Date)
  534. {
  535. //删除计划 - 到期删除
  536. RemoveTask(planid);
  537. _logger.LogDebug("AddHangfireAsync Error 计划已结束,计划名称:" + modelPlan.planname);
  538. return Error("计划已结束");
  539. }
  540. //Hangfire循环定时 - 方法
  541. b = await AddHangfirePlanWorkorderAsync(modelPlan);
  542. }
  543. if (b)
  544. {
  545. _logger.LogDebug("DistriWorkOrderPlanController/AddHangfireAsync 添加成功");
  546. return Success("添加成功");
  547. }
  548. else
  549. {
  550. _logger.LogError("DistriWorkOrderPlanController/AddHangfireAsync 添加失败");
  551. return Error("添加失败");
  552. }
  553. }
  554. /// <summary>
  555. /// 生成计划工单 - Hangfire循环定时 - 强制配送 - 方法
  556. /// </summary>
  557. /// <param name="planmodel"></param>
  558. /// <returns></returns>
  559. public async Task<bool> AddHangfirePlanWorkorderAsync(Distri_Workorder_Plan planmodel)
  560. {
  561. _logger.LogDebug("DistriWorkOrderPlanController/AddHangfirePlanWorkorderAsync Start ");
  562. var model_Hangfire = await _hangfireplan_distributionrepository.GetSingle(planmodel.hangfireid);
  563. int res = 0; int count = 0;
  564. #region 自动分配计划工单至计划参与人 - 获取参与人(电梯岗/配送岗) - 与排班没有关系,选中计划添加参与人 - 注释目的:生成计划工单时不执行参与人,在计划执行时间段推送给参与人(接口saveautoassignhangfire中添加参与人)
  565. ////获取当前时间
  566. //DateTime nowDateTime = DateTime.Now;
  567. //string nowDate = nowDateTime.ToString("yyyy-MM-dd");
  568. ////当天 - 获取当天排班列表
  569. //var listClassUser = (await _sys_classgroup_user_maprepository.Get(x => x.date == nowDate && x.isdelete == 0 && x.isstatus == 1 && x.projectid == planmodel.projectid)).ToList();
  570. ////当天参与计划 - 排班人列表
  571. //var listClassUserByPlan = listClassUser.Where(x => x.distri_planList != null && x.distri_planList.Count > 0 && x.isjoin == true && x.distri_planList.Select(p => p.planid).Contains(planmodel.id));
  572. //List<string> listUserCode = new List<string>();
  573. //foreach (var item in listClassUserByPlan)
  574. //{
  575. // listUserCode.Add(item.usercode);
  576. //}
  577. #endregion
  578. if (model_Hangfire != null)
  579. {
  580. #region 生成物品信息 - 主要是设置剩余数值
  581. List<DistributionGoodsListByTask> list_task = new List<DistributionGoodsListByTask>();
  582. foreach (var item_plan in planmodel.goodslist)
  583. {
  584. var model_task = new DistributionGoodsListByTask();
  585. model_task.goodsid = item_plan.goodsid;
  586. model_task.goodsname = item_plan.goodsname;
  587. model_task.typeid = item_plan.typeid;
  588. model_task.isremind = item_plan.isremind;
  589. model_task.remark = item_plan.remark;
  590. model_task.num = item_plan.num;
  591. model_task.usednum = 0; //使用数量 - 主要是设置剩余数值
  592. list_task.Add(model_task);
  593. }
  594. #endregion
  595. #region 不用
  596. //foreach (var item in model_Hangfire.extensiontime)
  597. //{
  598. // //Thread.Sleep(500);
  599. // var model = new Distri_Workorder_PlanTask();
  600. // #region 基本信息
  601. // model.channel = planmodel.channel;
  602. // model.projectid = planmodel.projectid;
  603. // model.planid = planmodel.id;
  604. // model.wocode = UniqueData.Gener("", 2); //计划工单编号 目前不用
  605. // model.planwostate = (int)EnumDistriWorkOrderPlanWOstate.create;
  606. // model.name = planmodel.planname;
  607. // model.content = planmodel.plancontent;
  608. // model.joinuserlist = new List<string>(); //计划工单参与人
  609. // model.goodslist = list_task;
  610. // model.deliverylist = planmodel.deliverylist;
  611. // model.deliveryname = planmodel.deliveryname;
  612. // model.deliverytel = planmodel.deliverytel;
  613. // model.starttime = DateTime.Parse(DateTime.Now.AddDays(item.startdate - 1).ToString("yyyy-MM-dd") + " " + item.starttime.ToString("HH:mm"));
  614. // model.endtime = DateTime.Parse(DateTime.Now.AddDays(item.enddate - 1).ToString("yyyy-MM-dd") + " " + item.endtime.ToString("HH:mm"));
  615. // model.createtby = planmodel.createtby;
  616. // model.createtime = DateTime.Now;
  617. // model.isdelete = 0;
  618. // #endregion
  619. // //DateTime starttime = DateTime.Parse(DateTime.Now.AddDays(item.startdate - 1).ToString("yyyy-MM-dd") + " " + item.starttime.ToString("HH:mm"));
  620. // //DateTime endtime = DateTime.Parse(DateTime.Now.AddDays(item.enddate - 1).ToString("yyyy-MM-dd") + " " + item.endtime.ToString("HH:mm"));
  621. // //开始时间小于当前时间不创建工单
  622. // //if (starttime <= DateTime.Now) //临时注释
  623. // //{ continue; }
  624. // if (await _distri_workorder_plantaskrepository.Add(model))
  625. // {
  626. // res += 1;
  627. // }
  628. // count++;
  629. //}
  630. #endregion
  631. var timeMode = new ExtensionTimeModel();
  632. foreach (var item in model_Hangfire.extensiontime)
  633. {
  634. string hourS = item.starttime.ToString("HH");
  635. string hourNowS = DateTime.Now.ToString("HH");
  636. if (hourNowS == hourS)
  637. {
  638. timeMode.startdate = item.startdate;
  639. timeMode.starttime = item.starttime;
  640. timeMode.enddate = item.enddate;
  641. timeMode.endtime = item.endtime;
  642. }
  643. break;
  644. }
  645. //Thread.Sleep(500);
  646. var model = new Distri_Workorder_PlanTask();
  647. #region 基本信息
  648. model.channel = planmodel.channel;
  649. model.projectid = planmodel.projectid;
  650. model.planid = planmodel.id;
  651. model.wocode = UniqueData.Gener("", 2); //计划工单编号 目前不用
  652. model.planwostate = (int)EnumDistriWorkOrderPlanWOstate.create;
  653. model.name = planmodel.planname;
  654. model.content = planmodel.plancontent;
  655. model.joinuserlist = new List<string>(); //计划工单参与人
  656. model.goodslist = list_task;
  657. model.deliverylist = planmodel.deliverylist;
  658. model.deliveryname = planmodel.deliveryname;
  659. model.deliverytel = planmodel.deliverytel;
  660. model.starttime = DateTime.Parse(DateTime.Now.AddDays(timeMode.startdate - 1).ToString("yyyy-MM-dd") + " " + timeMode.starttime.ToString("HH:mm"));
  661. model.endtime = DateTime.Parse(DateTime.Now.AddDays(timeMode.enddate - 1).ToString("yyyy-MM-dd") + " " + timeMode.endtime.ToString("HH:mm"));
  662. model.createtby = planmodel.createtby;
  663. model.createtime = DateTime.Now;
  664. model.isdelete = 0;
  665. #endregion
  666. DateTime starttime = DateTime.Parse(DateTime.Now.AddDays(timeMode.startdate - 1).ToString("yyyy-MM-dd") + " " + timeMode.starttime.ToString("HH:mm"));
  667. //DateTime endtime = DateTime.Parse(DateTime.Now.AddDays(item.enddate - 1).ToString("yyyy-MM-dd") + " " + item.endtime.ToString("HH:mm"));
  668. //开始时间小于当前时间不创建工单
  669. //if (starttime <= DateTime.Now) //临时注释
  670. //{ continue; }
  671. if (await _distri_workorder_plantaskrepository.Add(model))
  672. {
  673. _logger.LogError("AddHangfirePlanWorkorderAsync 定时生成计划工单成功,计划工单名称:" + planmodel.planname + ",计划工单内容:" + planmodel.plancontent);
  674. return true;
  675. }
  676. else
  677. {
  678. _logger.LogError("AddHangfirePlanWorkorderAsync 定时生成添加计划失败,计划工单名称:" + planmodel.planname + ",计划工单内容:" + planmodel.plancontent);
  679. return false;
  680. }
  681. }
  682. else
  683. {
  684. _logger.LogError("AddHangfirePlanWorkorderAsync 定时生成添加计划失败!计划工单名称:" + planmodel.planname + ",计划工单内容:" + planmodel.plancontent);
  685. return false;
  686. }
  687. }
  688. /// <summary>
  689. /// 自动定时计划 - 自动分配 随机工单 计划工单
  690. /// </summary>
  691. [AllowAnonymous]
  692. [HttpPost("saveautoassignhangfire")]
  693. public async Task<IActionResult> AddAutoAssignHangfireAsync(int wotype)
  694. {
  695. _logger.LogDebug("DistriWorkOrderPlanController/AddAutoAssignHangfireAsync ");
  696. if (wotype == (int)EnumDistributionWoType.autoassign)
  697. {
  698. DateTime dtnow = DateTime.Now;
  699. string nowDay = dtnow.ToString("yyyy-MM-dd");
  700. //1、配送岗 抢单时效 3分钟(某单子此时间内没人抢,系统强制分配)
  701. //抢单时效 - 分钟数
  702. int receive_Time = _distri_workorder_planrepository.GetLimitCount("ReceiveOrder_Time");
  703. //累积待配送量最大值
  704. int limit_Max = _distri_workorder_planrepository.GetLimitCount("Distribution_MaxNum");
  705. //待配送工单滞留时效 - 分钟数
  706. int stuck_Time = _distri_workorder_planrepository.GetLimitCount("StuckOrder_Time");
  707. DateTime dtnow_Out = dtnow.AddMinutes(-receive_Time);
  708. var list = (await _distri_workorderrepository.Get(x => x.wosorts == (int)EnumDistributionWoSorts.random && x.isdelete == 0)).ToList();
  709. //计划工单
  710. var list_PlanTask = await _distri_workorder_plantaskrepository.Get(x => x.isdelete == 0);
  711. //获取当天排班列表
  712. var listClassUser = (await _sys_classgroup_user_maprepository.Get(x => x.date == nowDay && x.isdelete == 0 && x.isstatus == 1)).ToList();
  713. //强制分配 - 添加接单人
  714. //待分配工单
  715. var list_wo = list.Where(x => x.createtime < dtnow_Out && x.wostate == (int)EnumDistributionState.create);
  716. var list_num = list.Where(x => x.wostate == (int)EnumDistributionState.assign).ToList();
  717. //计划工单 - 开始
  718. var list_PlanTask_start = list_PlanTask.Where(x => x.planwostate <= (int)EnumDistriWorkOrderPlanWOstate.start && x.joinuserlist.Count>0).ToList(); //x.joinuserlist !=null &&
  719. //班别列表
  720. var listClass = (await _sys_classgrouprepository.Get(x => x.isdelete == 0)).ToList();
  721. #region 获取用户符合条件的用户
  722. //var listUser = (await _sys_user_accountrepository.Get(x => x.delete_flag == false && x.lock_flag == false)).ToList();
  723. List<string> listUserCode_ByPlan = new List<string>();
  724. List<string> listUserCode = new List<string>();
  725. foreach (var item in listClassUser)
  726. {
  727. //获取条件 - 日期和班别code
  728. var list_code = new List<string> { }; //班别code
  729. var dayone = item.date;
  730. var list_r = item.classgroupList.ToList();
  731. foreach (var item_r in list_r)
  732. {
  733. if (item_r.roleList != null && item_r.roleList.Count > 0)
  734. {
  735. //角色 - 班别
  736. var mode_r = item_r.roleList.FirstOrDefault(x => x.ischeck == true); // && x.rolecode == rolecode // && x.rolecode == "SSY_PSG"
  737. if (mode_r != null)
  738. list_code.Add(item_r.code);
  739. }
  740. }
  741. if (list_code != null && list_code.Count > 0)
  742. {
  743. listClass = listClass.Where(x => list_code.Contains(x.code)).ToList();
  744. var model_Class = listClass.FirstOrDefault(x => DateTime.Parse(nowDay + " " + x.starttime) <= dtnow && DateTime.Parse(nowDay + " " + x.endtime) >= dtnow);
  745. if(model_Class!=null)
  746. {
  747. //判断人员下面是否有未完成的计划工单(如果没有,则分配随机工单)
  748. var list_p = list_PlanTask_start.Where(x => x.joinuserlist.Contains(item.usercode)).ToList();
  749. if (list_p.Count <= 0)
  750. {
  751. listUserCode_ByPlan.Add(item.usercode);
  752. }
  753. listUserCode.Add(item.usercode); //随机工单
  754. }
  755. //foreach (var item_Class in listClass)
  756. //{
  757. // //判断人员下面是否有未完成的计划工单(如果没有,则分配随机工单)
  758. // var list_p = list_PlanTask_start.Where(x => x.joinuserlist.Contains(item.usercode)).ToList();
  759. // if (list_p.Count <= 0)
  760. // {
  761. // listUserCode_ByPlan.Add(item.usercode);
  762. // }
  763. // listUserCode.Add(item.usercode); //随机工单
  764. //}
  765. }
  766. }
  767. #endregion
  768. #region 1、待强制分配工单
  769. //缓存里临时 配送列表
  770. var list_num_assign = list_num;
  771. var listwo = list_wo;
  772. foreach (var item in listwo)
  773. {
  774. //Thread.Sleep(500);
  775. #region 获取待配送工单量最少用户
  776. //var listUser = new List<string>();
  777. int n = limit_Max; //临时参数
  778. var usercodeMin = "";
  779. // 用户 和 工单数 list
  780. var list_usernum = new List<UserAndNumList>();
  781. foreach (var itemUser in listUserCode)
  782. {
  783. var model_usernum = new UserAndNumList();
  784. int num = list_num_assign.Count(x => x.touser.Contains(itemUser));
  785. model_usernum.num = num;
  786. model_usernum.usercode = itemUser;
  787. list_usernum.Add(model_usernum);
  788. //if (n > num)
  789. //{
  790. // n = num; //最小值赋值
  791. // usercodeMin = itemUser;
  792. //}
  793. }
  794. //获取单数最少的用户
  795. var model_minusernum = list_usernum.OrderBy(x => x.num).FirstOrDefault();
  796. if (model_minusernum != null)
  797. {
  798. n = model_minusernum.num;
  799. usercodeMin = model_minusernum.usercode;
  800. }
  801. #endregion
  802. var userinfo = (await _distri_sys_user_accountrepository.GetSingle(x => x.usercode == usercodeMin)); //x.delete_flag == false &&
  803. if (n < limit_Max)
  804. {
  805. //2019-01-04 修改bug 多次配送同一个人
  806. if (item.wostate == (int)EnumDistributionState.create && item.touser.Count <= 0)
  807. {
  808. #region 强制分配
  809. item.touser = new List<string>() { usercodeMin }; //配送岗 - 转派人/抢单人
  810. item.totype = (int)EnumDistributionTotype.assign;
  811. //配送工单状态:0创建工单,1转派或者抢单(待取货),2已取货(配送中),3货物异常(异常),4已完结/待评价,5已取消,6挂起 ,9已评价
  812. item.wostate = (int)EnumDistributionState.assign;
  813. item.assigtime = DateTime.Now;
  814. bool b = await _distri_workorderrepository.UpdateOne(item);
  815. #region 微信模板消息
  816. if (item.channel == 4)
  817. {
  818. var model_Receiver = item.receiverlist.FirstOrDefault();
  819. string content = "抢单人:" + usercodeMin + "-" + usercodeMin
  820. + "\n联系电话:" + (userinfo != null ? userinfo.mobile : "")
  821. + "\n收货地址:" + (model_Receiver != null ? model_Receiver.building_name : "") + (model_Receiver != null ? model_Receiver.floor_name : "") + " 科室:" + (model_Receiver != null ? model_Receiver.department_name : "")
  822. + "\n抢单时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
  823. _logger.LogError("neirong: " + content);
  824. SendWechatMsg(item.wocode, "配送员抢单成功!", "配送员已抢单成功,等待配送员取货", content, "", item.id, item.createtby); //默认是查看工单详情 PSDD
  825. }
  826. //int islast = item.wostate == (int)EnumDistributionState.finish ? 1 : 0; //是否最后一步 0否 1是
  827. //AddItems(item.id, item.wocode, item.wostate, item.wostate_elevator, channel, islast, usercode, "", "配送岗" + username + "抢单:", usercode);
  828. #endregion
  829. _logger.LogDebug("DistriWorkOrderPlanController/AddAutoAssignHangfireAsync 自动定时计划 强制分配,分配人:" + item.touser.ToJson() + "工单:" + item.wocode);
  830. #endregion
  831. //添加对应待配送(已分配)
  832. list_num_assign.Add(item);
  833. }
  834. }
  835. }
  836. #endregion
  837. #region 2、自动分配计划工单至计划参与人 - 获取参与人(电梯岗/配送岗) - 与排班没有关系,选中计划添加参与人
  838. //计划工单 - 新建
  839. var list_PlanTask_create = list_PlanTask.Where(x => x.planwostate == (int)EnumDistriWorkOrderPlanWOstate.create && x.joinuserlist.Count == 0 && x.joinuserlist.Count <= 0).ToList(); // && x.starttime <= dtnow && x.endtime >= dtnow
  840. foreach (var item_plan in list_PlanTask_create)
  841. {
  842. List<string> listUserCode_Plan = new List<string>();
  843. //当天 - 获取当天排班列表
  844. listClassUser = listClassUser.Where(x => x.projectid == item_plan.projectid).ToList();
  845. #region 1、提前计划排班 - PC端管理员,主管等昨天的提前计划排班
  846. //当天参与计划 - 排班人列表
  847. var listClassUserByPlan = listClassUser.Where(x => x.distri_planList != null && x.distri_planList.Count > 0 && x.isjoin == true && x.distri_planList.Select(p => p.planid).Contains(item_plan.planid));
  848. foreach (var item in listClassUserByPlan)
  849. {
  850. listUserCode_Plan.Add(item.usercode);
  851. }
  852. item_plan.joinuserlist = listUserCode_Plan.Distinct().ToList(); //计划工单参与人
  853. await _distri_workorder_plantaskrepository.UpdateOne(item_plan);
  854. #endregion
  855. #region 2、无人接的计划工单 - A、无提前计划排班;B、无人抢单,需要自动分配
  856. #region 获取待配送工单量最少用户
  857. int n = limit_Max; //临时参数
  858. var usercodeMin = "";
  859. // 用户 和 工单数 list
  860. var list_usernum = new List<UserAndNumList>();
  861. foreach (var itemUser in listUserCode_ByPlan)
  862. {
  863. var model_usernum = new UserAndNumList();
  864. int num = list_PlanTask_start.Count(x => x.joinuserlist.Contains(itemUser));
  865. model_usernum.num = num;
  866. model_usernum.usercode = itemUser;
  867. list_usernum.Add(model_usernum);
  868. }
  869. //获取单数最少的用户
  870. var model_minusernum = list_usernum.OrderBy(x => x.num).FirstOrDefault();
  871. if (model_minusernum != null)
  872. {
  873. n = model_minusernum.num;
  874. usercodeMin = model_minusernum.usercode;
  875. }
  876. #endregion
  877. if (n < limit_Max)
  878. {
  879. item_plan.joinuserlist = new List<string>() { usercodeMin }; //计划工单参与人
  880. await _distri_workorder_plantaskrepository.UpdateOne(item_plan);
  881. }
  882. #endregion
  883. _logger.LogDebug("DistriWorkOrderPlanController/AddAutoAssignHangfireAsync 自动定时计划工单 强制分配参与人,参与人:" + item_plan.joinuserlist.ToJson() + "计划工单:" + item_plan.wocode);
  884. }
  885. #endregion
  886. //配送岗 待配送工单滞留时效 30分钟(超时就记一次超时违规记录,可以有违规申诉)
  887. #region 3、违规修改
  888. DateTime dtnow_Wait = dtnow.AddMinutes(-stuck_Time);
  889. var list_Wait = list.Where(x => x.assigtime < dtnow_Wait && x.isoffence == 0 && x.wostate == (int)EnumDistributionState.assign); //1、从指派/抢单时间算 2、待配送 x.wostate_elevator == (int)EnumDistributionState_elevator.delivery &&
  890. foreach (var item in list_Wait)
  891. {
  892. item.isoffence = 1; //违规记录 - 待配送工单滞留时效
  893. await _distri_workorderrepository.UpdateOne(item);
  894. _logger.LogDebug("DistriWorkOrderPlanController/AddAutoAssignHangfireAsync 自动定时计划 违规处理,工单:" + item.wocode);
  895. }
  896. #endregion
  897. //_logger.LogDebug("DistriWorkOrderPlanController/AddAutoAssignHangfireAsync 自动定时计划创建成功");
  898. return Success("自动定时计划创建成功");
  899. }
  900. else
  901. {
  902. _logger.LogError("DistriWorkOrderPlanController/AddAutoAssignHangfireAsync 自动定时计划创建失败");
  903. return Error("自动定时计划创建失败");
  904. }
  905. }
  906. /// <summary>
  907. /// 用户 和 工单数 list
  908. /// </summary>
  909. public class UserAndNumList
  910. {
  911. /// <summary>
  912. /// 数量
  913. /// </summary>
  914. public int num { get; set; }
  915. /// <summary>
  916. /// 用户账号
  917. /// </summary>
  918. public string usercode { get; set; }
  919. }
  920. #endregion
  921. #region 设置定时计划
  922. #endregion
  923. #region 计划工单
  924. /// <summary>
  925. /// 获取计划工单列表分页 by page
  926. /// </summary>
  927. /// <param name="keyword"></param>
  928. /// <param name="stime"></param>
  929. /// <param name="etime"></param>
  930. /// <param name="pageindex"></param>
  931. /// <param name="pagesize"></param>
  932. /// <returns></returns>
  933. [HttpGet("getplantasklistbypage")]
  934. public IActionResult GetPlanTaskListByPageAsync(string keyword, string projectid, string stime, string etime, int datetype = -1, int planwostate = -1, int pageindex = 1, int pagesize = 10)
  935. {
  936. string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
  937. //var userstr = _signTokenService.GetUserInfoAsync(usercode).Result;
  938. //var userinfo = userstr.ToJObject()["data"].ToString().ToObject<UserInfoModel>();
  939. string allprojectrole = _configuration["allprojectrole"];
  940. var userinfos = _sys_user_accountRepository.GetUserInfo(usercode, allprojectrole);
  941. var userinfo = JsonHelper.JsonToEntity<UserAccountInfoModel>(userinfos.ToJson());
  942. //获取当天、本周、本月、本年、累计时间
  943. if (datetype != -1)
  944. {
  945. GetStartEndTime(datetype, out stime, out etime);
  946. }
  947. //获取数据
  948. int recordCount = 0;
  949. var result = _distri_workorder_planrepository.GetPlanTaskListsByPage(keyword, projectid, stime, etime, planwostate, userinfo, pageindex, pagesize, out recordCount);
  950. var obj = new
  951. {
  952. rows = result.ToList(),
  953. total = recordCount
  954. };
  955. return Success("获取成功", obj);
  956. }
  957. /// <summary>
  958. /// 获取计划工单详情
  959. /// </summary>
  960. [HttpGet("getplanworkordersingle")]
  961. public async Task<IActionResult> GetPlanTaskSingleAsync(string id,string projectid, int channelcode = 0)
  962. {
  963. string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
  964. if (string.IsNullOrEmpty(id))
  965. return Error("参数错误");
  966. var model = _distri_workorder_planrepository.GetPlanTaskDetails(id);
  967. if (model != null)
  968. {
  969. var userlist = (await _distri_sys_user_accountrepository.Get(x => x.delete_flag == false && x.type != 2)).ToList();
  970. //定时计划表
  971. var hangfireplan_List = (await _hangfireplan_distributionrepository.Get(x => x.plantype == (int)EnumDistributionPlanType.timing && x.isdelete == 0)).ToList();
  972. //计划表
  973. var plan_List = (await _distri_workorder_planrepository.Get(x => x.isdelete == 0 )).ToList();
  974. //分送工单表
  975. var wo_List = (await _distri_workorderrepository.Get(x => x.wosorts == (int)EnumDistributionWoSorts.plan && x.isdelete == 0 && x.plantaskid == model.id && (x.wostate == (int)EnumDistributionState.finish || x.wostate == (int)EnumDistributionState.evaluated))).ToList();
  976. #region 标记消息提醒工单(消息提醒,App推送)
  977. string goodsDetail = "";
  978. if (channelcode > 0)
  979. {
  980. if (model.planwostate == (int)EnumDistriWorkOrderPlanWOstate.start)
  981. {
  982. //维修工单号
  983. var listmap = await _wo_order_user_maprepository.Get(x => x.woid == model.id && x.wocode == model.wocode && x.channelcode == channelcode && x.readby == usercode);
  984. var modelmap = listmap.FirstOrDefault();
  985. goodsDetail = (model.goodslist != null && model.goodslist.Count > 0) ? " 配送计划工单物品:" + model.goodslist.Select(x => x.goodsname).ToJson() : "";
  986. if (modelmap == null)
  987. {
  988. //添加是否已读关系表
  989. modelmap = new Wo_Order_User_Map();
  990. modelmap.woid = model.id;
  991. modelmap.wocode = model.wocode;
  992. modelmap.wostate = model.planwostate;
  993. modelmap.readby = usercode;
  994. modelmap.channelcode = channelcode; //工单类型(枚举EnumOrderState) 维修工单 = 1, 保养工单 = 2, 运行工单 = 3, 超时工单 = 4, 配送工单 = 5, 计划工单 = 5
  995. modelmap.isread = 1;
  996. modelmap.isnotice = 1;
  997. modelmap.readtime = DateTime.Now;
  998. modelmap.note = (string.IsNullOrEmpty(model.content) ? "" : "计划工单内容:" + model.content) + goodsDetail; //保养内容
  999. // modelmap.note = model.maintaincontent;
  1000. bool b = await _wo_order_user_maprepository.Add(modelmap);
  1001. }
  1002. else
  1003. {
  1004. modelmap.isread = 1;
  1005. modelmap.isnotice = 1;
  1006. modelmap.note = (string.IsNullOrEmpty(model.content) ? "" : "计划工单内容:" + model.content) + goodsDetail; //保养内容
  1007. bool b = await _wo_order_user_maprepository.UpdateOne(modelmap);
  1008. }
  1009. }
  1010. }
  1011. #endregion
  1012. if (!string.IsNullOrEmpty(projectid))
  1013. userlist = userlist.Where(x => x.projectlist.Contains(projectid)).ToList();
  1014. if (model.joinuserlist != null && model.joinuserlist.Count > 0)
  1015. {
  1016. model.joinusertel = userlist.Where(y => model.joinuserlist.Contains(y.usercode)).Select(x => x.mobile).ToList();
  1017. }
  1018. if (!string.IsNullOrEmpty(model.planid) && hangfireplan_List != null && hangfireplan_List.Count > 0)
  1019. {
  1020. if (plan_List != null && plan_List.Count > 0)
  1021. {
  1022. var model_Plan = plan_List.FirstOrDefault(x => x.id == model.planid);
  1023. if (model_Plan != null)
  1024. {
  1025. model.plantimes = hangfireplan_List.FirstOrDefault(x => x.id == model_Plan.hangfireid).plantimes;
  1026. }
  1027. }
  1028. }
  1029. var newlist = wo_List.Select(x => new
  1030. {
  1031. id = x.id,
  1032. wocode = x.wocode,
  1033. receiverlist = x.receiverlist
  1034. });
  1035. var obj = new
  1036. {
  1037. model = model,
  1038. items = wo_List
  1039. };
  1040. return Success("获取计划工单成功", obj);
  1041. }
  1042. return Error("获取失败");
  1043. }
  1044. /// <summary>
  1045. /// 修改计划工单(修改且开始)
  1046. /// </summary>
  1047. [HttpPost("updateplantask")]
  1048. public async Task<IActionResult> UpdatePlanTaskAsync(string taskid, List<DistributionGoodsListByTask> goodslist)
  1049. {
  1050. string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
  1051. string username = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name).Value;
  1052. #region 判断验证
  1053. if (string.IsNullOrEmpty(taskid))
  1054. return Error("参数错误");
  1055. if (goodslist == null || goodslist.Count <= 0)
  1056. return Error("请选择物品种类");
  1057. int goodsnum = goodslist.Sum(x => x.num);
  1058. if (goodsnum <= 0)
  1059. return Error("请填写物品数量");
  1060. var model = await _distri_workorder_plantaskrepository.GetSingle(p => p.id == taskid);
  1061. if (model == null)
  1062. return Error("操作失败");
  1063. if (model.joinuserlist == null || model.joinuserlist.Count <= 0)
  1064. return Error("操作失败,参与人为空");
  1065. if (model.planwostate >= (int)EnumDistriWorkOrderPlanWOstate.start)
  1066. return Error("操作失败,计划工单已完成或已开始");
  1067. var pro = await _pro_project_infoRepository.GetSingle(model.projectid);
  1068. if (pro != null && pro.isend == 1)
  1069. return Error("该项目已暂停");
  1070. #endregion
  1071. //计划工单状态:0创建计划工单,1开始,2已完成
  1072. model.planwostate = (int)EnumDistriWorkOrderPlanWOstate.start;
  1073. model.goodslist = goodslist;
  1074. model.statetime = DateTime.Now; //开始时间
  1075. bool b = await _distri_workorder_plantaskrepository.UpdateOne(model);
  1076. if (b)
  1077. {
  1078. return Success("操作成功");
  1079. }
  1080. return Error("操作失败");
  1081. }
  1082. /// <summary>
  1083. /// 抢单 - 计划工单
  1084. /// </summary>
  1085. /// <param name="id"></param>
  1086. /// <param name="channel"></param>
  1087. /// <returns></returns>
  1088. [HttpPost("receiveplantask")]
  1089. public async Task<IActionResult> UpdateReceiveTaskAsync(string id)
  1090. {
  1091. string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
  1092. #region 验证判断
  1093. if (string.IsNullOrEmpty(id))
  1094. return Error("参数错误");
  1095. var model = await _distri_workorder_plantaskrepository.GetSingle(id);
  1096. if (model == null)
  1097. return Error("操作失败");
  1098. if (model.planwostate >= (int)EnumDistriWorkOrderPlanWOstate.start)
  1099. return Error("操作失败,计划工单已开始或已完成");
  1100. if (model.joinuserlist != null && model.joinuserlist.Count > 0)
  1101. return Error("操作失败,计划工单已有参与人或已抢单");
  1102. //判断此用户下是否有计划任务,如果有不让抢单,没有让抢单
  1103. var listWorkorder = (await _distri_workorder_plantaskrepository.Get(x => x.isdelete == 0 && x.joinuserlist.Contains(usercode) && x.planwostate < (int)EnumDistriWorkOrderPlanWOstate.finish)).ToList();
  1104. if (listWorkorder != null && listWorkorder.Count > 0)
  1105. return Error("您有" + listWorkorder.Count + "计划工单没有完成,不能进行抢单操作");
  1106. #endregion
  1107. model.joinuserlist = new List<string>() { usercode }; //参与人
  1108. //计划工单状态:0创建计划工单,1开始,2已完成
  1109. bool b = await _distri_workorder_plantaskrepository.UpdateOne(model);
  1110. if (b)
  1111. return Success("操作成功");
  1112. return Error("操作失败");
  1113. }
  1114. /// <summary>
  1115. /// 添加配合人 - 计划工单
  1116. /// </summary>
  1117. /// <param name="id"></param>
  1118. /// <param name="channel"></param>
  1119. /// <returns></returns>
  1120. [HttpPost("addreceiveplantask")]
  1121. public async Task<IActionResult> AddReceiveTaskAsync(string id,string user)
  1122. {
  1123. string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
  1124. #region 验证判断
  1125. if (string.IsNullOrEmpty(id))
  1126. return Error("参数错误");
  1127. var model = await _distri_workorder_plantaskrepository.GetSingle(id);
  1128. if (model == null)
  1129. return Error("操作失败");
  1130. if (model.planwostate >= (int)EnumDistriWorkOrderPlanWOstate.start)
  1131. return Error("操作失败,计划工单已开始或已完成");
  1132. if(string.IsNullOrEmpty(user))
  1133. return Error("操作失败,添加配合人不能为空");
  1134. if (model.joinuserlist.Contains(user))
  1135. return Error("操作失败," + user + "已存在,请不要重复添加");
  1136. ////判断此用户下是否有计划任务,如果有不让抢单,没有让抢单
  1137. //var listWorkorder = (await _distri_workorder_plantaskrepository.Get(x => x.isdelete == 0 && x.joinuserlist.Contains(user) && x.planwostate < (int)EnumDistriWorkOrderPlanWOstate.finish)).ToList();
  1138. //if (listWorkorder != null && listWorkorder.Count > 0)
  1139. // return Error("您有计划工单没有完成,不能进行抢单操作");
  1140. #endregion
  1141. model.joinuserlist.Add(user); //参与人
  1142. //计划工单状态:0创建计划工单,1开始,2已完成
  1143. bool b = await _distri_workorder_plantaskrepository.UpdateOne(model);
  1144. if (b)
  1145. return Success("操作成功");
  1146. return Error("操作失败");
  1147. }
  1148. /// <summary>
  1149. /// 删除计划工单
  1150. /// </summary>
  1151. /// <param name="ids"></param>
  1152. /// <returns></returns>
  1153. [HttpPost("deleteplantask")]
  1154. public async Task<IActionResult> RemovePlanTaskAsync(string[] ids)
  1155. {
  1156. string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
  1157. //使用逻辑删除
  1158. var res = 0;
  1159. if (ids == null && ids.Length <= 0)
  1160. return Error("请选择要删除的记录");
  1161. foreach (var item in ids)
  1162. {
  1163. var model = await _distri_workorder_plantaskrepository.GetSingle(item);
  1164. model.isdelete = 1;
  1165. model.deleteby = usercode;
  1166. model.deletetime = DateTime.Now;
  1167. if (await _distri_workorder_plantaskrepository.UpdateOne(model))
  1168. {
  1169. #region 查询此计划是否有未执行的工单,若有一并删除
  1170. var list_Wo = await _distri_workorderrepository.Get(r => r.plantaskid.Equals(item) && r.wostate == (int)EnumEquipmentRunningState.create);
  1171. if (list_Wo.Count() > 0)
  1172. {
  1173. foreach (var item_Dis in list_Wo)
  1174. {
  1175. item_Dis.isdelete = 1;
  1176. item_Dis.deleteby = usercode;
  1177. item_Dis.dealtime = DateTime.Now;
  1178. await _distri_workorderrepository.UpdateOne(item_Dis);
  1179. }
  1180. }
  1181. #endregion
  1182. res += 1;
  1183. }
  1184. }
  1185. if (res == ids.Length)
  1186. return Success("删除成功");
  1187. else if (res > 0 && res < ids.Length)
  1188. return Error("部分删除失败,请查看后重新操作");
  1189. else
  1190. return Error("删除失败,请查看后重新操作");
  1191. }
  1192. /// <summary>
  1193. /// 开始 - 计划工单
  1194. /// </summary>
  1195. /// <param name="ids"></param>
  1196. /// <returns></returns>
  1197. [HttpPost("startplantask")]
  1198. public async Task<IActionResult> StartAsync(string id)
  1199. {
  1200. string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
  1201. if (string.IsNullOrEmpty(id))
  1202. return Error("参数错误");
  1203. var model = await _distri_workorder_plantaskrepository.GetSingle(id);
  1204. if (model == null)
  1205. return Error("操作失败");
  1206. if (model.joinuserlist!=null && model.joinuserlist.Count>0)
  1207. return Error("操作失败,参与人为空");
  1208. if (model.planwostate >= (int)EnumDistriWorkOrderPlanWOstate.start)
  1209. return Error("操作失败,计划工单已完成或已开始");
  1210. //计划工单状态:0创建计划工单,1开始,2已完成
  1211. model.planwostate = (int)EnumDistriWorkOrderPlanWOstate.start;
  1212. model.statetime = DateTime.Now; //开始时间
  1213. bool b = await _distri_workorder_plantaskrepository.UpdateOne(model);
  1214. if (b)
  1215. {
  1216. return Success("操作成功");
  1217. }
  1218. return Error("操作失败");
  1219. }
  1220. /// <summary>
  1221. /// 完成 - 计划工单
  1222. /// </summary>
  1223. /// <param name="id"></param>
  1224. /// <param name="channel"></param>
  1225. /// <returns></returns>
  1226. [HttpPost("finishplantask")]
  1227. public async Task<IActionResult> UpdateFinishTaskAsync(string id)
  1228. {
  1229. string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
  1230. #region 验证判断
  1231. if (string.IsNullOrEmpty(id))
  1232. return Error("参数错误");
  1233. var model = await _distri_workorder_plantaskrepository.GetSingle(id);
  1234. if (model == null)
  1235. return Error("操作失败");
  1236. if (model.planwostate == (int)EnumDistriWorkOrderPlanWOstate.finish)
  1237. return Error("操作失败,计划工单已完成");
  1238. ////判断此用户下是否有计划任务,如果有不让抢单,没有让抢单
  1239. //var listWorkorder = (await _distri_workorder_plantaskrepository.Get(x => x.isdelete == 0 && x.planwostate < (int)EnumDistriWorkOrderPlanWOstate.finish)).ToList();
  1240. //if (listWorkorder != null && listWorkorder.Count > 0)
  1241. // return Error("您有计划工单没有完成,不能操作完成");
  1242. #endregion
  1243. foreach (var item in model.goodslist)
  1244. {
  1245. if (item.usednum < item.num)
  1246. return Error("操作错误,已配送物品" + item.goodsname + "数量:" + item.usednum + "小于计划工单物品" + item.goodsname + "数量:" + item.num + ",没有分送完物品,不能操作完成");
  1247. }
  1248. model.dealby = usercode; //处理人
  1249. model.dealtime = DateTime.Now; //处理时间
  1250. //计划工单状态:0创建计划工单,1开始,2已完成
  1251. model.planwostate = (int)EnumDistriWorkOrderPlanWOstate.finish;
  1252. bool b = await _distri_workorder_plantaskrepository.UpdateOne(model);
  1253. if (b)
  1254. {
  1255. return Success("操作成功");
  1256. }
  1257. return Error("操作失败");
  1258. }
  1259. #endregion
  1260. /// <summary>
  1261. /// 获取当天、本周、本月、本年、累计时间
  1262. /// </summary>
  1263. /// <param name="datetype"></param>
  1264. /// <param name="start"></param>
  1265. /// <param name="end"></param>
  1266. public void GetStartEndTime(int datetype, out string start, out string end)
  1267. {
  1268. start = string.Empty;
  1269. end = string.Empty;
  1270. var datenow = DateTime.Now;
  1271. var datestart = datenow;
  1272. var dateend = datenow;
  1273. switch (datetype)
  1274. {
  1275. case 0://当天
  1276. break;
  1277. case 1://本周
  1278. int n = (int)datenow.DayOfWeek == 0 ? 7 : (int)datenow.DayOfWeek;
  1279. datestart = datenow.AddDays(1 - n);//本周周一
  1280. dateend = datestart.AddDays(6);//本周周日
  1281. break;
  1282. case 2://本月
  1283. datestart = datenow.AddDays(1 - datenow.Day); //本月月初
  1284. dateend = datestart.AddMonths(1).AddDays(-1); //本月月末
  1285. break;
  1286. case 3://本年
  1287. datestart = new DateTime(datenow.Year, 1, 1); //本年年初
  1288. dateend = new DateTime(datenow.Year, 12, 31); //本年年末
  1289. break;
  1290. case 4://全部
  1291. break;
  1292. default:
  1293. break;
  1294. }
  1295. if (datetype != 4)
  1296. {
  1297. start = datestart.ToString("yyyy-MM-dd");
  1298. end = dateend.ToString("yyyy-MM-dd");
  1299. }
  1300. }
  1301. #region 微信方法
  1302. /// <summary>
  1303. /// 发送微信模板消息
  1304. /// </summary>
  1305. /// <param name="wocode">工单编号</param>
  1306. /// <param name="title">标题</param>
  1307. /// <param name="content">内容</param>
  1308. /// <param name="url">链接地址</param>
  1309. /// <param name="openid">接收方</param>
  1310. /// <param name="templateid">模板id</param>
  1311. private async void SendWechatMsg(string wocode, string title, string statename, string content, string menucode, string url, string openid, string templateid = "csH1KSQMz8nMnZhlcH7gpOo1aAIZZLiXecYlhGFzvuE")
  1312. {
  1313. if (string.IsNullOrEmpty(menucode))
  1314. menucode = "PSDD";
  1315. url = "menucode=" + menucode + "&id=" + url;
  1316. var obj = new
  1317. {
  1318. first = new { value = title, color = "#173177" },
  1319. keyword1 = new { value = statename },
  1320. keyword2 = new { value = wocode },
  1321. remark = new { value = content }
  1322. };
  1323. await _wechatservice.SendTemplateMsg(openid, url, obj.ToJson(), templateid);
  1324. }
  1325. ///// <summary>
  1326. ///// 发送微信消息
  1327. ///// </summary>
  1328. ///// <param name="wocode">工单编号</param>
  1329. ///// <param name="title">标题</param>
  1330. ///// <param name="content">内容</param>
  1331. ///// <param name="url">链接地址</param>
  1332. ///// <param name="openid">接收方</param>
  1333. //private async void SendWechatMessage(string wocode, string title, string content, string url, string openid)
  1334. //{
  1335. // url = "menucode=CKXQ&id=" + url;
  1336. // content = content + "\n时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
  1337. // await _wechatservice.SendNewsMsg(openid, title, content, url);
  1338. //}
  1339. #endregion
  1340. }
  1341. }