Files
tnb.server/ProductionMgr/Tnb.ProductionMgr/PrdCancelCloseDownService.cs

496 lines
23 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Dynamic;
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.Message.Service;
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.BasicData.Entities;
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 MessageTemplateEntity = JNPF.Message.Entitys.Entity.MessageTemplateEntity;
namespace Tnb.ProductionMgr
{
/// <summary>
/// 业务实现:生产管理
/// </summary>
[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 readonly SendMessageService _sendMessageService;
private static readonly Dictionary<string, object> _dicWorkStationAndShopRelacion = new();
private static Dictionary<string, object> _dicWorkShop = new();
private const string PUSHRULEID = "27121606262805";//异常停机的推送规则id
public PrdCancelCloseDownService(
ISqlSugarRepository<PrdCancelClosedown> 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();
}
/// <summary>
/// 根据设备ID获取异常关机信息
/// </summary>
/// <param name="eqpId"></param>
/// <returns></returns>
[HttpGet]
public async Task<dynamic> GetClosedownEndList([FromRoute] string eqpId)
{
if (_dicWorkShop.Count < 1)
{
List<OrganizeEntity> orgs = await _db.Queryable<OrganizeEntity>().Where(it => it.Category == "workstation").ToListAsync();
if (orgs?.Count > 0)
{
List<string> shopIds = orgs.Select(x =>
{
string shopId = "";
string[] orgTree = x.OrganizeIdTree.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (orgTree?.Length > 1)
{
shopId = orgTree[^2];
_dicWorkStationAndShopRelacion[x.EnCode] = shopId;
}
return shopId;
}).Where(x => !x.IsNullOrEmpty()).ToList();
if (shopIds?.Count > 0)
{
_dicWorkShop = await _db.Queryable<OrganizeEntity>().Where(it => it.Category == "department" && shopIds.Contains(it.Id)).ToDictionaryAsync(x => x.Id, x => x.FullName);
}
}
}
List<ClosedownEndListOutput> result = new();
PrdCancelClosedown closeDown = await _db.Queryable<PrdCancelClosedown>().FirstAsync(it => it.eqp_id == eqpId);
if (closeDown != null)
{
if (!closeDown.reason.IsNullOrEmpty())
{
EqpEquipment? eqp = await _db.Queryable<EqpEquipment>().FirstAsync(it => it.id == eqpId);
EqpEquipType? eqpTypeInfo = null;
if (eqp != null)
{
eqpTypeInfo = await _db.Queryable<EqpEquipType>().FirstAsync(it => it.id == eqp.equip_type_id);
}
string[] reasonArr = closeDown.reason.Split(",");
foreach (string reason in reasonArr)
{
ClosedownEndListOutput ot = new();
if (eqp != null)
{
if (_dicWorkStationAndShopRelacion.ContainsKey(eqp.station_code))
{
string? 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;
}
/// <summary>
/// 获取停机历史记录
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet]
public async Task<dynamic> GetClosedownHistory([FromQuery] ClosedownHistoryQuery input)
{
List<ClosedownHistoryOutput> pagedList = await _db.Queryable<PrdCancelClosedownRecord>()
.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(DbTimeFormat.SS) : null,
closedown_end_time = it.closedown_end_time.HasValue ? it.closedown_end_time.Value.ToString(DbTimeFormat.SS) : null,
closedown_time = it.closedown_time,
})
.ToListAsync();
return pagedList;
}
/// <summary>
/// 根据设备id获取生产任务单信息模具信息
/// </summary>
/// <param name="eqpId">设备Id</param>
/// <remarks>
/// returns:
/// <br/>{
/// <br/> mo_task_code:任务单编号
/// <br/> mold_code:模具编号
/// <br/> mold_name:模具名称
/// <br/>}
/// </remarks>
[HttpGet]
public async Task<dynamic> GetInfoFromEqpId([FromRoute] string eqpId)
{
dynamic info = new ExpandoObject();
PrdMoTask moTask = await _db.Queryable<PrdMoTask>().Where(it => it.mo_task_status == DictConst.InProgressEnCode).FirstAsync(it => it.eqp_id == eqpId);
if (moTask != null)
{
ToolMolds? mold = await _db.Queryable<ToolMolds>().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;
}
/// <summary>
/// 异常停机-开始
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[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");
}
EqpEquipment? eqp = await _db.Queryable<EqpEquipment>().FirstAsync(it => it.id == input.eqp_id);
PrdCancelClosedown cancelCloseDown = input.Adapt<PrdCancelClosedown>();
EqpRepairApply? eqpRepairApply = null;
BasPushRuleD basPushRuleD = await _db.Queryable<BasPushRuleD>().FirstAsync(x => x.push_rule_id == PUSHRULEID && x.ordinal == 1);
try
{
DbResult<bool> result = await _db.Ado.UseTranAsync(async () =>
{
List<PrdMoTask>? 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();
PrdCancelClosedownRecord record = cancelCloseDown.Adapt<PrdCancelClosedownRecord>();
record.eqp_code = eqp?.code;
record.eqp_name = eqp?.name;
_ = await _db.Insertable(record).ExecuteCommandAsync();
string? moldId = moTaskList.First().mold_id;
if (!moldId.IsNullOrEmpty())
{
ToolMolds mold = await _moldService.GetListById(moldId);
ToolMoldMaintainTask maintaindTask = new()
{
mold_id = moldId,
code = mold?.mold_code ?? "",
create_id = _userManager.UserId,
status = DictConst.UnMaintainStatusCode,
create_time = DateTime.Now
};
await _maintainTaskService.Create(maintaindTask);
}
string reason = "";
if (!string.IsNullOrEmpty(input.reason))
{
List<PrdCancelClosedownReason> prdCancelClosedownReasons = await _db.Queryable<PrdCancelClosedownReason>().ToListAsync();
string[] reasonArr = input.reason.Split(",");
List<string?> 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<MessageSendModel> list = await _sendMessageService.SendTest(basPushRuleD.send_config_id);
List<string> toUsers = JsonConvert.DeserializeObject<List<string>>(eqp.responsibler_id);
foreach (MessageSendModel item in list)
{
foreach (MessageSendParam param in item.paramJson)
{
if (param.field == "equip_code")
{
param.value = eqp.code;
}
}
item.toUser = toUsers;
}
foreach (MessageSendModel item in list)
{
_ = await _sendMessageService.SendMessage(item, new Dictionary<string, object>());
}
}
}
else
{
throw Oops.Oh(ErrorCode.COM1001);
}
});
if (result.IsSuccess)
{
BasPushRuleH basPushRuleH = await _db.Queryable<BasPushRuleH>().SingleAsync(x => x.id == PUSHRULEID);
if (basPushRuleH?.enabled == 1)
{
string sendConfigId = basPushRuleD?.send_config_id ?? "";
List<MessageSendModel> 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} ?";
ContentModel comtentModel = new()
{
// comtentModel.cron = (2 * 60).ToString();
cron = cron,
interfaceId = "",
interfaceName = "",
parameter = new List<InterfaceParameter>(),
localHostTaskId = "PushMsgTimeWorker/PushMsg",
startTime = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
// comtentModel.endTime = DateTimeOffset.Now.AddSeconds(3).ToUnixTimeMilliseconds().ToString();
TenantId = _userManager?.TenantId,
TenantDbName = _userManager?.TenantDbName,
ConnectionConfig = _userManager?.ConnectionConfig,
Token = _userManager?.ToKen
};
foreach (MessageSendModel item in sendModels)
{
foreach (MessageSendParam param in item.paramJson)
{
if (param.field == "equip_code")
{
param.value = eqp?.code;
}
}
}
TimeTaskCrInput timeTaskCrInput = new()
{
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<TimeTaskEntity>().Where(x => x.EnCode == timeTaskCrInput.enCode).FirstAsync();
BasPushRuleLog basPushRuleLog = new()
{
push_rule_id = PUSHRULEID,
timetask_id = timeTaskEntity?.Id,
biz_id = eqpRepairApply.id,
ordinal = 1,
is_push = 1,
};
_ = await _db.Insertable<BasPushRuleLog>(basPushRuleLog).ExecuteCommandAsync();
}
}
}
}
catch (Exception ex)
{
Log.Error("停机开始失败", ex);
// await _db.Ado.RollbackTranAsync();
throw;
}
}
/// <summary>
/// 停机结束
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[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();
PrdCancelClosedown closeDown = await _db.Queryable<PrdCancelClosedown>().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();
PrdCancelClosedownRecord record = closeDown.Adapt<PrdCancelClosedownRecord>();
//计算停机时间间隔,以小时为单位
if (record.closedown_start_time.HasValue && record.closedown_end_time.HasValue)
{
double 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<List<MessageSendModel>> GetSendParamJson(string id)
{
List<MessageSendModel> list = await _db.Queryable<MessageSendTemplateEntity, MessageTemplateEntity>((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<MessageDataTypeEntity>().Where(u => u.Type == "1" && u.EnCode == a.MessageType).Select(u => u.FullName),
msgTemplateName = b.FullName,
sendConfigId = a.SendConfigId,
templateId = a.TemplateId,
}).ToListAsync();
foreach (MessageSendModel? item in list)
{
// 是否存在参数.
bool flag = await _db.Queryable<MessageSmsFieldEntity>().AnyAsync(x => x.TemplateId == item.templateId && x.DeleteMark == null);
item.paramJson = flag
? await _db.Queryable<MessageTemplateParamEntity, MessageTemplateEntity, MessageSmsFieldEntity>((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()
: await _db.Queryable<MessageTemplateParamEntity, MessageTemplateEntity>((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;
}
}
}