496 lines
23 KiB
C#
496 lines
23 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|