using System; using System.Collections.Generic; using System.Dynamic; using System.Linq; using System.Text; using System.Threading.Tasks; using Aop.Api.Domain; using JNPF.Common.Core.Manager; using JNPF.Common.Dtos.Message; using JNPF.Common.Enums; using JNPF.Common.Extension; using JNPF.Common.Security; using JNPF.DependencyInjection; using JNPF.DynamicApiController; using JNPF.FriendlyException; using JNPF.Logging; using JNPF.Message.Entitys.Entity; using JNPF.Systems.Entitys.Permission; using JNPF.Systems.Entitys.System; using JNPF.Systems.Interfaces.System; using JNPF.TaskScheduler; using JNPF.TaskScheduler.Entitys.Dto.TaskScheduler; using JNPF.TaskScheduler.Entitys.Model; using Mapster; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using SqlSugar; using Tnb.BasicData; using Tnb.EquipMgr.Entities; using Tnb.EquipMgr.Entities.Dto; using Tnb.EquipMgr.Interfaces; using Tnb.ProductionMgr.Entities; using Tnb.ProductionMgr.Entities.Dto.PrdManage; using Tnb.ProductionMgr.Interfaces; using Tnb.BasicData.Entities; using MessageTemplateEntity = JNPF.Message.Entitys.Entity.MessageTemplateEntity; using JNPF.Message.Service; namespace Tnb.ProductionMgr { /// /// 业务实现:生产管理 /// [ApiDescriptionSettings(Tag = ModuleConst.Tag, Area = ModuleConst.Area, Order = 700)] [Route("api/[area]/[controller]/[action]")] public class PrdCancelCloseDownService : IPrdCancelCloseDownService, IDynamicApiController, ITransient { private readonly ISqlSugarClient _db; private readonly IToolMoldMaintainTaskService _maintainTaskService; private readonly IToolMoldsService _moldService; private readonly IPrdMoTaskService _prdMoTaskService; private readonly IUserManager _userManager; private readonly IBillRullService _billRullService; private readonly TimeTaskService _timeTaskService; private SendMessageService _sendMessageService; private static Dictionary _dicWorkStationAndShopRelacion = new Dictionary(); private static Dictionary _dicWorkShop = new Dictionary(); private const string PUSHRULEID = "27121606262805";//异常停机的推送规则id public PrdCancelCloseDownService( ISqlSugarRepository repository, IPrdMoTaskService prdMoTaskService, IToolMoldsService moldsService, IToolMoldMaintainTaskService maintainTaskService, IBillRullService billRullService, TimeTaskService timeTaskService, SendMessageService sendMessageService, IUserManager userManager ) { _prdMoTaskService = prdMoTaskService; _maintainTaskService = maintainTaskService; _moldService = moldsService; _userManager = userManager; _billRullService = billRullService; _timeTaskService = timeTaskService; _sendMessageService = sendMessageService; _db = repository.AsSugarClient(); } /// /// 根据设备ID获取异常关机信息 /// /// /// [HttpGet] public async Task GetClosedownEndList([FromRoute] string eqpId) { if (_dicWorkShop.Count < 1) { var orgs = await _db.Queryable().Where(it => it.Category == "workstation").ToListAsync(); if (orgs?.Count > 0) { var shopIds = orgs.Select(x => { var shopId = ""; var orgTree = x.OrganizeIdTree.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (orgTree?.Length > 1) { shopId = orgTree[orgTree.Length - 2]; _dicWorkStationAndShopRelacion[x.EnCode] = shopId; } return shopId; }).Where(x => !x.IsNullOrEmpty()).ToList(); if (shopIds?.Count > 0) { _dicWorkShop = await _db.Queryable().Where(it => it.Category == "department" && shopIds.Contains(it.Id)).ToDictionaryAsync(x => x.Id, x => x.FullName); } } } var result = new List(); var closeDown = await _db.Queryable().FirstAsync(it => it.eqp_id == eqpId); if (closeDown != null) { if (!closeDown.reason.IsNullOrEmpty()) { var eqp = await _db.Queryable().FirstAsync(it => it.id == eqpId); EqpEquipType eqpTypeInfo = null; if (eqp != null) eqpTypeInfo = await _db.Queryable().FirstAsync(it => it.id == eqp.equip_type_id); var reasonArr = closeDown.reason.Split(","); foreach (var reason in reasonArr) { ClosedownEndListOutput ot = new(); if (eqp != null) { if (_dicWorkStationAndShopRelacion.ContainsKey(eqp.station_code)) { var shopId = _dicWorkStationAndShopRelacion[eqp.station_code].ToString(); ot.workshop_name = _dicWorkShop.ContainsKey(shopId) ? _dicWorkShop[shopId].ToString()! : ""; } } ot.reason = reason; ot.eqp_code = eqp?.code; ot.eqp_type_code = eqpTypeInfo?.code; ot.operator_name = _userManager.RealName; ot.remark = closeDown.remark; ot.closeddown_start_time = closeDown.closedown_start_time; result.Add(ot); } } } if (result.Count < 1) { ClosedownEndListOutput output = new(); result.Add(output); } return result; } /// /// 获取停机历史记录 /// /// /// [HttpGet] public async Task GetClosedownHistory([FromQuery] ClosedownHistoryQuery input) { var pagedList = await _db.Queryable() .WhereIF(!string.IsNullOrEmpty(input.eqpName), it => it.eqp_name.Contains(input.eqpName)) .WhereIF(input.beginTime.HasValue, it => it.closedown_start_time.Value >= input.beginTime) .WhereIF(input.endTime.HasValue, it => it.closedown_start_time.Value <= input.endTime) .Select(it => new ClosedownHistoryOutput { eqp_code = it.eqp_code, eqp_name = it.eqp_name, closedown_start_time = it.closedown_start_time.HasValue ? it.closedown_start_time.Value.ToString("yyyy-MM-dd HH:mm:ss") : null, closedown_end_time = it.closedown_end_time.HasValue ? it.closedown_end_time.Value.ToString("yyyy-MM-dd HH:mm:ss") : null, closedown_time = it.closedown_time, }) .ToListAsync(); return pagedList; } /// /// 根据设备id获取生产任务单信息,模具信息 /// /// 设备Id /// /// returns: ///
{ ///
mo_task_code:任务单编号 ///
mold_code:模具编号 ///
mold_name:模具名称 ///
} ///
[HttpGet] public async Task GetInfoFromEqpId([FromRoute] string eqpId) { dynamic info = new ExpandoObject(); var moTask = await _db.Queryable().Where(it => it.mo_task_status == DictConst.InProgressEnCode).FirstAsync(it => it.eqp_id == eqpId); if (moTask != null) { var mold = await _db.Queryable().FirstAsync(it => it.id == moTask.mo_id); info.mo_task_code = moTask.mo_task_code; info.mold_code = mold?.mold_code; info.mold_name = mold?.mold_name; } return info; } /// /// 异常停机-开始 /// /// /// [HttpPost] public async Task CloseDownStart(CloseDownStartInput input) { if (input == null) throw new ArgumentNullException("input"); if (input.eqp_id.IsNullOrWhiteSpace()) throw new ArgumentException($"parameter {nameof(input.eqp_id)} not be null or empty"); var eqp = await _db.Queryable().FirstAsync(it => it.id == input.eqp_id); var cancelCloseDown = input.Adapt(); EqpRepairApply eqpRepairApply = null; BasPushRuleD basPushRuleD = await _db.Queryable().FirstAsync(x => x.push_rule_id == PUSHRULEID && x.ordinal == 1); try { DbResult result = await _db.Ado.UseTranAsync(async () => { var moTaskList = await _prdMoTaskService.GetListByEqpId(input.eqp_id); if (moTaskList?.Count > 1) throw new AppFriendlyException($"设备{input.eqp_id},目前有两条进行中的生产任务", 500); if (moTaskList?.Count > 0) { cancelCloseDown.id = SnowflakeIdHelper.NextId(); cancelCloseDown.eqp_id = input.eqp_id; cancelCloseDown.create_id = _userManager.UserId; cancelCloseDown.create_time = DateTime.Now; cancelCloseDown.closedown_start_time = DateTime.Now; await _db.Insertable(cancelCloseDown).ExecuteCommandAsync(); var record = cancelCloseDown.Adapt(); record.eqp_code = eqp?.code; record.eqp_name = eqp?.name; await _db.Insertable(record).ExecuteCommandAsync(); var moldId = moTaskList.First().mold_id; if (!moldId.IsNullOrEmpty()) { var mold = await _moldService.GetListById(moldId); var maintaindTask = new ToolMoldMaintainTask(); maintaindTask.mold_id = moldId; maintaindTask.code = mold?.mold_code ?? ""; maintaindTask.create_id = _userManager.UserId; maintaindTask.status = DictConst.UnMaintainStatusCode; maintaindTask.create_time = DateTime.Now; await _maintainTaskService.Create(maintaindTask); } string reason = ""; if (!string.IsNullOrEmpty(input.reason)) { List prdCancelClosedownReasons = await _db.Queryable().ToListAsync(); string[] reasonArr = input.reason.Split(","); var reasonList = prdCancelClosedownReasons.Where(x => reasonArr.Contains(x.id)).Select(x => x.reason).ToList(); reason = string.Join(',', reasonList); } string code = await _billRullService.GetBillNumber("EqpRepair"); eqpRepairApply = new EqpRepairApply() { code = code, name = eqp.name + "停机", equip_id = input.eqp_id, status = Tnb.EquipMgr.RepairApplyStatus.TOBEEXECUTED, description = reason, create_id = _userManager.UserId, create_time = DateTime.Now, remark = input.remark, }; await _db.Insertable(eqpRepairApply).ExecuteCommandAsync(); if (!string.IsNullOrEmpty(eqp.responsibler_id)) { List list = await _sendMessageService.SendTest(basPushRuleD.send_config_id); List toUsers = JsonConvert.DeserializeObject>(eqp.responsibler_id); foreach (var item in list) { foreach (var param in item.paramJson) { if (param.field=="equip_code") { param.value = eqp.code; } } item.toUser = toUsers; } foreach (var item in list) { await _sendMessageService.SendMessage(item, new Dictionary()); } } } else throw Oops.Oh(ErrorCode.COM1001); }); if (result.IsSuccess) { BasPushRuleH basPushRuleH = await _db.Queryable().SingleAsync(x=>x.id==PUSHRULEID); if (basPushRuleH?.enabled == 1) { string sendConfigId = basPushRuleD?.send_config_id ?? ""; List sendModels = await GetSendParamJson(sendConfigId); if (sendModels != null && sendModels.Count > 0) { DateTime executeTime = DateTime.Now.AddMinutes(basPushRuleD.interval); // string cron = $"0 {executeTime.Minute} {executeTime.Hour} {executeTime.Day} {executeTime.Month} ? {executeTime.Year}"; string cron = $"0 {executeTime.Minute} {executeTime.Hour} {executeTime.Day} {executeTime.Month} ?"; var comtentModel = new ContentModel(); // comtentModel.cron = (2 * 60).ToString(); comtentModel.cron = cron; comtentModel.interfaceId = ""; comtentModel.interfaceName = ""; comtentModel.parameter = new List(); comtentModel.localHostTaskId = "PushMsgTimeWorker/PushMsg"; comtentModel.startTime = DateTimeOffset.Now.ToUnixTimeMilliseconds(); // comtentModel.endTime = DateTimeOffset.Now.AddSeconds(3).ToUnixTimeMilliseconds().ToString(); comtentModel.TenantId = _userManager?.TenantId; comtentModel.TenantDbName = _userManager?.TenantDbName; comtentModel.ConnectionConfig = _userManager?.ConnectionConfig; comtentModel.Token = _userManager?.ToKen; foreach (var item in sendModels) { foreach (var param in item.paramJson) { if (param.field == "equip_code") { param.value = eqp?.code; } } } TimeTaskCrInput timeTaskCrInput = new TimeTaskCrInput() { enCode = DateTime.Now.ToString("yyyyMMddHHmmss"), fullName = "临时推送消息" + DateTime.Now.ToString("yyyyMMddHHmmss"), executeType = "3", executeContent = comtentModel.ToJsonString(), description = JsonConvert.SerializeObject(sendModels[0].paramJson), sortCode = 9999, enabledMark = 1, }; await _timeTaskService.Create(timeTaskCrInput,false); TimeTaskEntity timeTaskEntity = await _db.Queryable().Where(x => x.EnCode == timeTaskCrInput.enCode).FirstAsync(); BasPushRuleLog basPushRuleLog = new BasPushRuleLog() { push_rule_id = PUSHRULEID, timetask_id = timeTaskEntity?.Id, biz_id = eqpRepairApply.id, ordinal = 1, is_push = 1, }; await _db.Insertable(basPushRuleLog).ExecuteCommandAsync(); } } } } catch (Exception ex) { Log.Error("停机开始失败", ex); // await _db.Ado.RollbackTranAsync(); throw; } } /// /// 停机结束 /// /// /// [HttpPost] public async Task CloseDownEnd(CloseDownStartInput input) { if (input == null) throw new ArgumentNullException("input"); if (input.eqp_id.IsNullOrWhiteSpace()) throw new ArgumentException($"parameter {nameof(input.eqp_id)} not be null or empty"); try { await _db.Ado.BeginTranAsync(); var closeDown = await _db.Queryable().Where(it => it.eqp_id == input.eqp_id).OrderByDescending(it => it.closedown_start_time).FirstAsync(); if (closeDown != null) { closeDown.closedown_end_time = DateTime.Now; await _db.Updateable(closeDown).ExecuteCommandAsync(); var record = closeDown.Adapt(); //计算停机时间间隔,以小时为单位 if (record.closedown_start_time.HasValue && record.closedown_end_time.HasValue) { var interval = record.closedown_end_time.Value.Subtract(record.closedown_start_time.Value).TotalHours; record.closedown_time = Convert.ToDecimal(interval); } await _db.Updateable(record).ExecuteCommandAsync(); await _db.Ado.CommitTranAsync(); } } catch (Exception ex) { Log.Error("停机结束失败", ex); await _db.Ado.RollbackTranAsync(); throw; } } private async Task> GetSendParamJson(string id) { var list = await _db.Queryable((a, b) => new JoinQueryInfos(JoinType.Left, a.TemplateId == b.Id)) .Where((a, b) => a.SendConfigId == id && a.DeleteMark == null && b.DeleteMark == null) .Select((a, b) => new MessageSendModel { accountConfigId = a.AccountConfigId, id = a.Id, messageType = SqlFunc.Subqueryable().Where(u => u.Type == "1" && u.EnCode == a.MessageType).Select(u => u.FullName), msgTemplateName = b.FullName, sendConfigId = a.SendConfigId, templateId = a.TemplateId, }).ToListAsync(); foreach (var item in list) { // 是否存在参数. var flag = await _db.Queryable().AnyAsync(x => x.TemplateId == item.templateId && x.DeleteMark == null); if (flag) { item.paramJson = await _db.Queryable((a, b, c) => new JoinQueryInfos(JoinType.Left, a.TemplateId == b.Id, JoinType.Left, a.TemplateId == c.TemplateId)) .Where((a, b, c) => a.TemplateId == item.templateId && a.DeleteMark == null && b.DeleteMark == null && a.Field == c.Field && a.Field != "@flowLink") .Select((a, b) => new MessageSendParam { field = a.Field, fieldName = a.FieldName, id = a.Id, templateCode = b.TemplateCode, templateId = a.TemplateId, templateName = b.FullName, templateType = b.TemplateType }).ToListAsync(); } else { item.paramJson = await _db.Queryable((a, b) => new JoinQueryInfos(JoinType.Left, a.TemplateId == b.Id)) .Where((a, b) => a.TemplateId == item.templateId && a.DeleteMark == null && b.DeleteMark == null && a.Field != "@flowLink") .Where((a, b) => b.Title.Contains(a.Field) || b.Content.Contains(a.Field)) .Select((a, b) => new MessageSendParam { field = a.Field, fieldName = a.FieldName, id = a.Id, templateCode = b.TemplateCode, templateId = a.TemplateId, templateName = b.FullName, templateType = b.TemplateType }).ToListAsync(); } } return list; } } }