using AutoMapper; using APT.BaseData.Domain.Entities; using APT.BaseData.Domain.Entities; using APT.BaseData.Domain.Enums; using APT.BaseData.Domain.IServices; using APT.BaseData.Domain.Msg; using APT.Infrastructure.Core; using APT.Utility; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using APT.Infrastructure.Api; namespace APT.BaseData.Services.DomainServices { public partial class PFCodeRuleSerialService : CommonService, IPFCodeRuleSerialService { public PFCodeRuleSerialService(IRepository repository) : base(repository) { } /// /// 跑批 /// /// public bool RunBatch() { //增加跑批日志表 var logs = this.GetEntities(i => i.IS_COMPLETE == false); if (logs.Any()) { foreach (var l in logs) { if (l.START_TIME <= DateTime.Now.AddHours(-6)) { l.IS_COMPLETE = true; } } this.BantchUpdateEntity(logs); //如果有未完成的跑批数据不继续跑批,如超过6个小时,则认为是异常中断 if (logs.Any(i => i.START_TIME > DateTime.Now.AddHours(-6))) { return false; } } //开始跑批 const int Day = -2; var date = DateTime.Now.ToString("yyyyMMdd"); var nextDate = DateTime.Now.AddDays(1).ToString("yyyyMMdd"); var codeRules = this.GetEntities(i => i.ENABLE_STATUS == (int)FMEnableStatusEnum.启用, new BaseFilter(), new string[] { "Nav_Org" }).ToList(); if (codeRules.Any()) { //跑批日志表增加一条数据 var log = new T_PF_CODE_RULE_RUN_LOG { ID = Guid.NewGuid(), CREATE_TIME = DateTime.Now, START_TIME = DateTime.Now, IS_COMPLETE = false, ORG_ID = codeRules.FirstOrDefault().ORG_ID }; this.AddEntity(log); try { //var dbCodeRuleSerials=this.GetEntities(t => t.STATUS == (int)PFCodeRuleStatus.未用).ToList(); List codeRuleSerials = new List(); foreach (var rule in codeRules) { DoGenSerialByRule(rule, date, codeRuleSerials); } //预生成第二天的编码 因为工厂通常有夜班 编码未必可以及时生成 foreach (var rule in codeRules) { DoGenSerialByRule(rule, nextDate, codeRuleSerials); } this.BantchAddEntity(codeRuleSerials); var towDay = DateTime.Now.AddDays(Day).ToString("yyyyMMdd"); var serialLogs = this.GetEntities(i => i.DATE_VALUE != null && string.Compare(i.DATE_VALUE, towDay) <= 0, true).ToList(); if (serialLogs.Any()) { var seialAddLogs = new List(); foreach (var s in serialLogs) { seialAddLogs.Add(s); if (seialAddLogs.Count >= 10000) { AddLogByInValidSerial(seialAddLogs); seialAddLogs.Clear(); } } AddLogByInValidSerial(seialAddLogs); } } finally { var oldLog = this.GetEntity(log.ID.ToString()); if (oldLog != null) { oldLog.END_TIME = DateTime.Now; oldLog.IS_COMPLETE = true; this.UpdateEntity(oldLog); } } } return true; } private void AddLogByInValidSerial(List list) { if (list == null || !list.Any()) return; this.DeleteEntity(list); //var seialAddLogs = new List(); //foreach (var s in list) //{ // var log = new T_PF_CODE_RULE_SERIAL_LOG();// Mapper.Map(s); // log.ORG_ID = log.ORG_ID; // CopyUtils.CopyObject(log, s); // seialAddLogs.Add(log); //} //this.BantchAddEntity(seialAddLogs); } private void DoGenSerialByRule(T_PF_CODE_RULE rule, string date, List codeRuleSerials) { Expression> expression = t => t.ORG_ID == rule.ORG_ID && t.CODE_TYPE == rule.CODE_TYPE; if (!rule.IS_IGNORE_DATE.HasValue || !rule.IS_IGNORE_DATE.Value) expression = expression.And(t => t.DATE_VALUE == date); var pageFilter = new BasePageFilter(1, 1); pageFilter.Sort = "NUM"; pageFilter.Order = DbOrder.DESC; var maxDbCodeRuleSerial = this.GetOrderPageEntities(expression, pageFilter); int num = 0; T_PF_CODE_RULE_SERIAL maxCodeRuleSerail = null; if (maxDbCodeRuleSerial.Items.Any()) { maxCodeRuleSerail = maxDbCodeRuleSerial.Items.FirstOrDefault(); if (maxCodeRuleSerail != null) num = maxCodeRuleSerail.NUM; } num++; Expression> expression1 = t => t.ORG_ID == rule.ORG_ID && t.CODE_TYPE == rule.CODE_TYPE && t.STATUS == (int)PFCodeRuleStatus.未用; if (!rule.IS_IGNORE_DATE.HasValue || !rule.IS_IGNORE_DATE.Value) expression1 = expression1.And(t => t.DATE_VALUE == date); var minUnUseSerial = this.GetEntity(expression1, new BaseFilter() { Order = DbOrder.ASC, Sort = "NUM" }); int minUnUseNum = 0; if (minUnUseSerial != null) minUnUseNum = minUnUseSerial.NUM - 1; else if (maxCodeRuleSerail != null && maxCodeRuleSerail.STATUS != (int)PFCodeRuleStatus.未用) minUnUseNum = maxCodeRuleSerail.NUM; var maxQty = rule.QTY == null || rule.QTY == 0 ? 100 : rule.QTY; maxQty += minUnUseNum; var serial = new T_PF_CODE_RULE_SERIAL { ORG_ID = rule.ORG_ID, CODE_TYPE = rule.CODE_TYPE, DATE_VALUE = rule.IS_IGNORE_DATE.HasValue && rule.IS_IGNORE_DATE.Value ? null : date, STATUS = (int)PFCodeRuleStatus.未用 }; //位数限制 var ruleMaxQty = Math.Floor(Math.Pow(10, rule.SERIAL_NUM_LEN) - 1); if (maxQty > (int)ruleMaxQty) maxQty = (int)ruleMaxQty; for (int i = num; i <= maxQty; i++) { var cpSerial = (T_PF_CODE_RULE_SERIAL)serial.Clone(); cpSerial.ID = Guid.NewGuid(); cpSerial.NUM = i; cpSerial.SERIAL = string.Concat(rule.CODE_PREFIX, (rule.Nav_Org == null ? string.Empty : (rule.Nav_Org.CODE)), (rule.IS_IGNORE_DATE.HasValue && rule.IS_IGNORE_DATE.Value ? string.Empty : date), i.ToString().PadLeft(rule.SERIAL_NUM_LEN, '0')); codeRuleSerials.Add(cpSerial); if (codeRuleSerials.Count >= 1000) { this.BantchAddEntity(codeRuleSerials); codeRuleSerials.Clear(); } } } /// /// 手动触发 /// /// /// public bool GenSerial(KeywordFilter filter) { var date = DateTime.Now.ToString("yyyyMMdd"); var type = int.Parse(filter.Keyword); filter.Sort = string.Empty; var codeRule = this.GetEntity(i => i.CODE_TYPE == type, filter, new string[] { "Nav_Org" }); if (codeRule == null) throw new Exception(ErrMsg.PF_ERR_CODE_RULE_TYPE + ":" + type); List codeRuleSerials = new List(); DoGenSerialByRule(codeRule, date, codeRuleSerials); this.BantchAddEntity(codeRuleSerials); return true; } /// /// 检验预取流水 /// /// public bool SerialCheck() { var checkSerial = this.GetEntities(i => i.STATUS == (int)PFCodeRuleStatus.预取 && i.RELEASE_TIME != null && i.RELEASE_TIME < DateTime.Now).ToList(); if (checkSerial.Any()) { checkSerial.ForEach(i => { i.STATUS = (int)PFCodeRuleStatus.未用; i.TAKE_TIME = null; i.RELEASE_TIME = null; }); //commit //1.初始化当前的数据 this.BantchUpdateEntity(checkSerial); } return true; } } }