diff --git a/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/AddAndonInput.cs b/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/AddAndonInput.cs
new file mode 100644
index 00000000..b4fc2c9d
--- /dev/null
+++ b/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/AddAndonInput.cs
@@ -0,0 +1,11 @@
+namespace Tnb.ProductionMgr.Entities.Dto
+{
+ public class AddAndonInput
+ {
+ public string andon_type_id { get; set; }
+
+ public string andon_info_id { get; set; }
+
+ public string andon_breakdown_id { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/AndonPadListInput.cs b/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/AndonPadListInput.cs
new file mode 100644
index 00000000..2053e8bc
--- /dev/null
+++ b/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/AndonPadListInput.cs
@@ -0,0 +1,17 @@
+namespace Tnb.ProductionMgr.Entities.Dto
+{
+ public class AndonPadListInput
+ {
+ public string andon_type_id { get; set; }
+
+ ///
+ /// 页码.
+ ///
+ public int currentPage { get; set; }
+
+ ///
+ /// 页容量.
+ ///
+ public int pageSize { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/AndonPadListOutput.cs b/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/AndonPadListOutput.cs
new file mode 100644
index 00000000..d9354b4a
--- /dev/null
+++ b/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/AndonPadListOutput.cs
@@ -0,0 +1,15 @@
+namespace Tnb.ProductionMgr.Entities.Dto
+{
+ public class AndonPadListOutput
+ {
+ public string id { get; set; }
+ public string andon_info_name { get; set; }
+ public string promoter_name { get; set; }
+ public string repair_name { get; set; }
+ public string? promoter_time { get; set; }
+ public string? response_time { get; set; }
+ public string? start_repair_time { get; set; }
+ public string? end_repair_time { get; set; }
+ public string? confirm_time { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/AndonInfo.cs b/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/AndonInfo.cs
new file mode 100644
index 00000000..99adab74
--- /dev/null
+++ b/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/AndonInfo.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using JNPF.Common.Contracts;
+using JNPF.Common.Security;
+using SqlSugar;
+
+namespace Tnb.ProductionMgr.Entities.Entity
+{
+ [SugarTable("andon_info")]
+ public partial class AndonInfo : BaseEntity
+ {
+ public AndonInfo()
+ {
+ id = SnowflakeIdHelper.NextId();
+ }
+ public string? region_name { get; set; }
+
+ public string? name { get; set; }
+
+ public string? push_rule_id { get; set; }
+
+ ///
+ /// 故障类别
+ ///
+ public string? andon_type { get; set; }
+
+
+ ///
+ /// 故障
+ ///
+ public string? breakdown_id { get; set; }
+ public string? status { get; set; }
+ public string? personnel { get; set; }
+ public string? position { get; set; }
+ public string? role { get; set; }
+ public string? repair { get; set; }
+
+ public string? create_id { get; set; }
+ public DateTime? create_time { get; set; }
+ public string? modify_id { get; set; }
+ public DateTime? modify_time { get; set; }
+ public string? remark { get; set; }
+ public string? send_config_id { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/AndonRecords.cs b/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/AndonRecords.cs
index 68b8deb0..a66f9be0 100644
--- a/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/AndonRecords.cs
+++ b/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/AndonRecords.cs
@@ -36,5 +36,14 @@ namespace Tnb.ProductionMgr.Entities
public string? modify_id { get; set; }
public DateTime? modify_time { get; set; }
public string? remark { get; set; }
+ public string? andon_type_id { get; set; }
+ public string? andon_info_id { get; set; }
+ public string? repair_id { get; set; }
+
+ public DateTime? response_time { get; set; }
+ public DateTime? start_repair_time { get; set; }
+ public DateTime? end_repair_time { get; set; }
+ public DateTime? confirm_time { get; set; }
+
}
}
diff --git a/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/AndonTypecs.cs b/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/AndonTypecs.cs
new file mode 100644
index 00000000..0507aec2
--- /dev/null
+++ b/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/AndonTypecs.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using JNPF.Common.Contracts;
+using JNPF.Common.Security;
+using SqlSugar;
+
+namespace Tnb.ProductionMgr.Entities
+{
+ [SugarTable("andon_type")]
+ public partial class AndonType : BaseEntity
+ {
+ public AndonType()
+ {
+ id = SnowflakeIdHelper.NextId();
+ }
+ ///
+ /// 名称
+ ///
+ public string? name { get; set; }
+
+ public string? remark { get; set; }
+
+ public string? create_id { get; set; }
+ public DateTime? create_time { get; set; }
+ public string? modify_id { get; set; }
+ public DateTime? modify_time { get; set; }
+ ///
+ /// 所属组织
+ ///
+ public string? org_id { get; set; }
+
+ }
+}
diff --git a/ProductionMgr/Tnb.ProductionMgr.Interfaces/IAndonRecordService.cs b/ProductionMgr/Tnb.ProductionMgr.Interfaces/IAndonRecordService.cs
new file mode 100644
index 00000000..340f595f
--- /dev/null
+++ b/ProductionMgr/Tnb.ProductionMgr.Interfaces/IAndonRecordService.cs
@@ -0,0 +1,48 @@
+using Tnb.ProductionMgr.Entities.Dto;
+
+namespace Tnb.ProductionMgr.Interfaces
+{
+ ///
+ /// 安灯记录服务
+ ///
+ public interface IAndonRecordService
+ {
+ ///
+ /// 根据安灯类别获取安灯记录列表
+ ///
+ ///
+ ///
+ public Task GetAndonPadList(AndonPadListInput input);
+
+ ///
+ /// 新增一条andon记录
+ ///
+ ///
+ ///
+ public Task AddAndon(AddAndonInput input);
+
+ ///
+ /// 响应andon
+ ///
+ ///
+ public Task ResponseAndon(Dictionary dic);
+
+ ///
+ /// 开始处理andon
+ ///
+ ///
+ public Task StartAndon(Dictionary dic);
+
+ ///
+ /// 结束处理andon
+ ///
+ ///
+ public Task EndAndon(Dictionary dic);
+
+ ///
+ /// 确认andon
+ ///
+ ///
+ public Task ConfirmAndon(Dictionary dic);
+ }
+}
\ No newline at end of file
diff --git a/ProductionMgr/Tnb.ProductionMgr.Interfaces/IAndonTypeService.cs b/ProductionMgr/Tnb.ProductionMgr.Interfaces/IAndonTypeService.cs
new file mode 100644
index 00000000..e8fe549c
--- /dev/null
+++ b/ProductionMgr/Tnb.ProductionMgr.Interfaces/IAndonTypeService.cs
@@ -0,0 +1,17 @@
+
+
+namespace Tnb.ProductionMgr.Interfaces
+{
+ ///
+ /// 安灯类别服务
+ ///
+ public interface IAndonTypeService
+ {
+ ///
+ /// 获取所有安灯类别和对应记录数
+ ///
+ ///
+ public Task GetAndonTypeAndRecords();
+
+ }
+}
\ No newline at end of file
diff --git a/ProductionMgr/Tnb.ProductionMgr/AndonRecordService.cs b/ProductionMgr/Tnb.ProductionMgr/AndonRecordService.cs
new file mode 100644
index 00000000..37acd24f
--- /dev/null
+++ b/ProductionMgr/Tnb.ProductionMgr/AndonRecordService.cs
@@ -0,0 +1,324 @@
+using JNPF.Common.Core.Manager;
+using JNPF.Common.Dtos.Message;
+using JNPF.Common.Enums;
+using JNPF.Common.Filter;
+using JNPF.Common.Security;
+using JNPF.DependencyInjection;
+using JNPF.DynamicApiController;
+using JNPF.FriendlyException;
+using JNPF.Message.Entitys.Entity;
+using JNPF.Message.Service;
+using JNPF.Systems.Entitys.Permission;
+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.ProductionMgr.Entities;
+using Tnb.ProductionMgr.Entities.Dto;
+using Tnb.ProductionMgr.Entities.Dto.PrdManage;
+using Tnb.ProductionMgr.Entities.Entity;
+using Tnb.ProductionMgr.Interfaces;
+using Tnb.BasicData.Entities;
+using JNPF.Systems.Entitys.System;
+using JNPF.Message.Entitys.Entity;
+using MessageTemplateEntity = JNPF.Message.Entitys.Entity.MessageTemplateEntity;
+
+namespace Tnb.ProductionMgr
+{
+ [ApiDescriptionSettings(Tag = ModuleConst.Tag, Area = ModuleConst.Area, Order = 700)]
+ [Route("api/[area]/[controller]/[action]")]
+ public class AndonRecordService: IAndonRecordService, IDynamicApiController, ITransient
+ {
+ private readonly ISqlSugarClient _db;
+ private readonly IUserManager _userManager;
+ private SendMessageService _sendMessageService;
+ private readonly TimeTaskService _timeTaskService;
+
+ public AndonRecordService(ISqlSugarRepository repository,
+ SendMessageService sendMessageService,
+ TimeTaskService timeTaskService,
+ IUserManager userManager)
+ {
+ _userManager = userManager;
+ _sendMessageService = sendMessageService;
+ _timeTaskService = timeTaskService;
+ _db = repository.AsSugarClient();
+ }
+
+ [HttpPost]
+ public async Task GetAndonPadList(AndonPadListInput input)
+ {
+ var result = await _db.Queryable()
+ .LeftJoin((a, b) => a.andon_info_id == b.id)
+ .LeftJoin((a, b, c) => a.repair_id == c.Id)
+ .LeftJoin((a, b, c, d) => a.create_id == d.Id)
+ .Where((a, b, c, d) => a.andon_type_id == input.andon_type_id)
+ .Select((a, b, c, d) => new AndonPadListOutput
+ {
+ id = a.id,
+ andon_info_name = b.name,
+ promoter_name = d.RealName,
+ repair_name = c.RealName,
+ promoter_time = a.create_time == null ? "" : a.create_time.Value.ToString("yyyy-MM-dd hh:mm:ss"),
+ response_time = a.response_time == null ? "" : a.response_time.Value.ToString("yyyy-MM-dd hh:mm:ss"),
+ start_repair_time = a.start_repair_time == null ? "" : a.start_repair_time.Value.ToString("yyyy-MM-dd hh:mm:ss"),
+ end_repair_time = a.end_repair_time == null ? "" : a.end_repair_time.Value.ToString("yyyy-MM-dd hh:mm:ss"),
+ confirm_time = a.confirm_time == null ? "" : a.confirm_time.Value.ToString("yyyy-MM-dd hh:mm:ss"),
+ }).ToPagedListAsync(input.currentPage, input.pageSize);
+
+ return PageResult.SqlSugarPageResult(result);
+
+ }
+
+ [HttpPost]
+ public async Task AddAndon(AddAndonInput input)
+ {
+ AndonInfo andonInfo = await _db.Queryable().SingleAsync(x => x.id == input.andon_info_id);
+ AndonRecords andonRecords = input.Adapt();
+ DbResult result = await _db.Ado.UseTranAsync(async () =>
+ {
+
+ andonRecords.create_time = DateTime.Now;
+ andonRecords.create_id = _userManager.UserId;
+
+
+ List toUsers = new List();
+
+ if (!string.IsNullOrEmpty(andonInfo.personnel))
+ {
+ toUsers.AddRange(JsonConvert.DeserializeObject>(andonInfo.personnel));
+ }
+
+ if (!string.IsNullOrEmpty(andonInfo.position))
+ {
+
+ toUsers.AddRange(_db.Queryable().Where(x => andonInfo.position.Contains(x.Id)).Select(s => s.UserId).ToList());
+ }
+
+ if (!string.IsNullOrEmpty(andonInfo.role))
+ {
+
+ toUsers.AddRange(_db.Queryable().Where(x => andonInfo.role.Contains(x.Id)).Select(s => s.UserId).ToList());
+ }
+
+ if (toUsers.Count() > 0)
+ {
+ List list = await _sendMessageService.SendTest(andonInfo.send_config_id);
+
+ foreach (var item in list)
+ {
+ item.toUser = toUsers;
+ }
+
+ foreach (var item in list)
+ {
+ await _sendMessageService.SendMessage(item, new Dictionary());
+ }
+ }
+
+ });
+
+ if (result.IsSuccess)
+ {
+ BasPushRuleH basPushRuleH = await _db.Queryable().SingleAsync(x=>x.id==andonInfo.push_rule_id);
+ BasPushRuleD basPushRuleD = await _db.Queryable().FirstAsync(x => x.push_rule_id == andonInfo.push_rule_id && x.ordinal == 1);
+ 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)
+ // {
+ // }
+ //
+ TimeTaskCrInput timeTaskCrInput = new TimeTaskCrInput()
+ {
+ enCode = DateTime.Now.ToString("yyyyMMddHHmmss"),
+ fullName = "andon推送消息" + 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 = andonInfo.push_rule_id,
+ timetask_id = timeTaskEntity?.Id,
+ biz_id = andonRecords.id,
+ ordinal = 1,
+ is_push = 1,
+ };
+
+ await _db.Insertable(basPushRuleLog).ExecuteCommandAsync();
+ }
+ }
+
+ }
+
+ if(!result.IsSuccess) throw Oops.Oh(ErrorCode.COM1008);
+ return result.IsSuccess ? "发起成功" : result.ErrorMessage;
+ }
+
+ [HttpPost]
+ public async Task ResponseAndon(Dictionary dic)
+ {
+ string id = dic.ContainsKey("id") ? dic["id"] : "";
+ AndonRecords andonRecords = await _db.Queryable().SingleAsync(x => x.id == id);
+ if (andonRecords != null)
+ {
+ if (!string.IsNullOrEmpty(andonRecords.repair_id))
+ {
+ UserEntity user = await _db.Queryable().SingleAsync(x => x.Id == andonRecords.repair_id);
+ throw Oops.Bah($"{user.RealName}已响应");
+ }
+ else
+ {
+ await _db.Updateable()
+ .SetColumns(x => x.repair_id == _userManager.UserId)
+ .SetColumns(x=>x.response_time==DateTime.Now)
+ .ExecuteCommandAsync();
+ return true;
+ }
+ }
+ else
+ {
+ throw Oops.Bah($"无该andon记录");
+ }
+ }
+
+ [HttpPost]
+ public async Task StartAndon(Dictionary dic)
+ {
+ string id = dic.ContainsKey("id") ? dic["id"] : "";
+ AndonRecords andonRecords = await _db.Queryable().SingleAsync(x => x.id == id);
+ if (andonRecords != null)
+ {
+ await _db.Updateable()
+ .SetColumns(x=>x.start_repair_time==DateTime.Now)
+ .ExecuteCommandAsync();
+ return true;
+ }
+ else
+ {
+ throw Oops.Bah($"无该andon记录");
+ }
+ }
+
+ [HttpPost]
+ public async Task EndAndon(Dictionary dic)
+ {
+ string id = dic.ContainsKey("id") ? dic["id"] : "";
+ AndonRecords andonRecords = await _db.Queryable().SingleAsync(x => x.id == id);
+ if (andonRecords != null)
+ {
+ await _db.Updateable()
+ .SetColumns(x=>x.end_repair_time==DateTime.Now)
+ .ExecuteCommandAsync();
+ return true;
+ }
+ else
+ {
+ throw Oops.Bah($"无该andon记录");
+ }
+ }
+
+ [HttpPost]
+ public async Task ConfirmAndon(Dictionary dic)
+ {
+ string id = dic.ContainsKey("id") ? dic["id"] : "";
+ AndonRecords andonRecords = await _db.Queryable().SingleAsync(x => x.id == id);
+ if (andonRecords != null)
+ {
+ await _db.Updateable()
+ .SetColumns(x=>x.confirm_time==DateTime.Now)
+ .ExecuteCommandAsync();
+ return true;
+ }
+ else
+ {
+ throw Oops.Bah($"无该andon记录");
+ }
+ }
+
+ 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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProductionMgr/Tnb.ProductionMgr/AndonTypeService.cs b/ProductionMgr/Tnb.ProductionMgr/AndonTypeService.cs
new file mode 100644
index 00000000..26ac4ea8
--- /dev/null
+++ b/ProductionMgr/Tnb.ProductionMgr/AndonTypeService.cs
@@ -0,0 +1,45 @@
+using JNPF.Common.Core.Manager;
+using JNPF.Common.Filter;
+using JNPF.DependencyInjection;
+using JNPF.DynamicApiController;
+using JNPF.Systems.Entitys.Permission;
+using Microsoft.AspNetCore.Mvc;
+using SqlSugar;
+using Tnb.BasicData.Entities;
+using Tnb.EquipMgr.Interfaces;
+using Tnb.ProductionMgr.Entities;
+using Tnb.ProductionMgr.Entities.Dto;
+using Tnb.ProductionMgr.Entities.Dto.PrdManage;
+using Tnb.ProductionMgr.Entities.Entity;
+using Tnb.ProductionMgr.Interfaces;
+
+namespace Tnb.ProductionMgr
+{
+ [ApiDescriptionSettings(Tag = ModuleConst.Tag, Area = ModuleConst.Area, Order = 700)]
+ [Route("api/[area]/[controller]/[action]")]
+ public class AndonTypeService : IAndonTypeService, IDynamicApiController, ITransient
+ {
+ private readonly ISqlSugarClient _db;
+ private readonly IUserManager _userManager;
+ public AndonTypeService(ISqlSugarRepository repository,IUserManager userManager)
+ {
+ _userManager = userManager;
+ _db = repository.AsSugarClient();
+ }
+
+
+ [HttpPost]
+ public async Task GetAndonTypeAndRecords()
+ {
+ var result = await _db.Queryable()
+ .Select((a) => new
+ {
+ andon_type_id = a.id,
+ andon_type_name = a.name,
+ record_count = SqlFunc.Subqueryable().Where(x=>x.andon_type_id==a.id).Count(),
+ }).ToListAsync();
+ return result;
+ }
+
+ }
+}
\ No newline at end of file