using AutoMapper; using Kean.Domain; using Kean.Domain.Order.Models; using Kean.Infrastructure.Database; using Kean.Infrastructure.Database.Repository.Default; using Kean.Infrastructure.Database.Repository.Default.Entities; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; namespace Kean.Infrastructure.Repository { /// /// 订单仓库 /// public class OrderRepository : Domain.Order.Repositories.IOrderRepository { private readonly IMapper _mapper; // 模型映射 private readonly IDefaultDb _database; // 默认数据库 /// /// 构造函数 /// public OrderRepository( IMapper mapper, IDefaultDb database) { _mapper = mapper; _database = database; } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.GetType 方法 */ public async Task GetType(int id) { return _mapper.Map(await _database.From() .Where(t => t.TYPE_FLAG == true && t.TYPE_ID == id) .Single()); } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsTypeCodeExist 方法 */ public async Task IsTypeCodeExist(string code, int? igrone) { var schema = _database.From().Where(t => t.TYPE_FLAG == true && t.TYPE_CODE == code); if (igrone.HasValue) { schema = schema.Where(t => t.TYPE_ID != igrone.Value); } return (await schema.Single(t => new { Count = Function.Count(t.TYPE_ID) })).Count > 0; } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsTypeNameExist 方法 */ public async Task IsTypeNameExist(string name, int? igrone) { var schema = _database.From().Where(t => t.TYPE_FLAG == true && t.TYPE_NAME == name); if (igrone.HasValue) { schema = schema.Where(t => t.TYPE_ID != igrone.Value); } return (await schema.Single(t => new { Count = Function.Count(t.TYPE_ID) })).Count > 0; } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsTypeUsing 方法 */ public async Task IsTypeUsing(int id) { return (await _database.From() .Where(p => p.PLAN_TYPE == id) .Single(p => new { Count = Function.Count(p.PLAN_ID) })) .Count > 0; } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.CreateType 方法 */ public async Task CreateType(Domain.Order.Models.Type type) { var entity = _mapper.Map(type); entity.TYPE_FLAG = true; entity.UPDATE_TIME = entity.CREATE_TIME = DateTime.Now; var id = await _database.From().Add(entity); return Convert.ToInt32(id); } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.ModifyType 方法 */ public Task ModifyType(Domain.Order.Models.Type type) { var entity = _mapper.Map(type); entity.TYPE_FLAG = true; entity.UPDATE_TIME = DateTime.Now; return _database.From().Update(entity, nameof(T_PLAN_TYPE.CREATE_TIME)); } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.DeleteType 方法 */ public async Task DeleteType(int id) { await _database.From() .Where(t => t.TYPE_ID == id) .Update(new { TYPE_FLAG = false, UPDATE_TIME = DateTime.Now }); } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsFlowExist 方法 */ public async Task IsFlowExist(int id) { return (await _database.From() .Where(f => f.FLOW_FLAG == true && f.FLOW_ID == id) .Single(f => new { Count = Function.Count(f.FLOW_ID) })).Count > 0; } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsFlowNameExist 方法 */ public async Task IsFlowNameExist(string name, int? igrone) { var schema = _database.From().Where(f => f.FLOW_FLAG == true && f.FLOW_NAME == name); if (igrone.HasValue) { schema = schema.Where(f => f.FLOW_ID != igrone.Value); } return (await schema.Single(f => new { Count = Function.Count(f.FLOW_ID) })).Count > 0; } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsFlowUsing 方法 */ public async Task IsFlowUsing(int id) { return (await _database.From() .Where(p => p.PLAN_FLOW == id) .Single(p => new { Count = Function.Count(p.PLAN_ID) })) .Count > 0; } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.CreateFlow 方法 */ public async Task CreateFlow(Flow flow) { var timestamp = DateTime.Now; var planFlow = _mapper.Map(flow); planFlow.FLOW_FLAG = true; planFlow.UPDATE_TIME = planFlow.CREATE_TIME = timestamp; var id = Convert.ToInt32(await _database.From().Add(planFlow)); if (flow.Nodes?.Any() == true) { var nodeId = new Dictionary(); foreach (var item in flow.Nodes) { var planFlowNode = _mapper.Map(item); planFlowNode.FLOW_ID = id; planFlowNode.UPDATE_TIME = planFlowNode.CREATE_TIME = timestamp; nodeId.Add(item.Id, item.Id = Convert.ToInt32(await _database.From().Add(planFlowNode))); } foreach (var item in flow.Paths) { item.Source = nodeId[item.Source]; item.Target = nodeId[item.Target]; var planFlowPath = _mapper.Map(item); ; planFlowPath.FLOW_ID = id; planFlowPath.UPDATE_TIME = planFlowPath.CREATE_TIME = timestamp; item.Id = Convert.ToInt32(await _database.From().Add(planFlowPath)); } } return id; } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.ModifyFlow 方法 */ public async Task ModifyFlow(Flow flow) { var timestamp = DateTime.Now; var planFlow = _mapper.Map(flow); planFlow.FLOW_FLAG = true; planFlow.UPDATE_TIME = timestamp; await _database.From().Update(planFlow, nameof(T_PLAN_FLOW.CREATE_TIME)); if (flow.Nodes != null || flow.Paths != null) { await _database.From() .Where(n => n.FLOW_ID == flow.Id) .Delete(); await _database.From() .Where(p => p.FLOW_ID == flow.Id) .Delete(); if (flow.Nodes.Any()) { var nodeId = new Dictionary(); foreach (var item in flow.Nodes) { var planFlowNode = _mapper.Map(item); planFlowNode.FLOW_ID = flow.Id; planFlowNode.UPDATE_TIME = planFlowNode.CREATE_TIME = timestamp; nodeId.Add(item.Id, item.Id = Convert.ToInt32(await _database.From().Add(planFlowNode))); } foreach (var item in flow.Paths) { item.Source = nodeId[item.Source]; item.Target = nodeId[item.Target]; var planFlowPath = _mapper.Map(item); ; planFlowPath.FLOW_ID = flow.Id; planFlowPath.UPDATE_TIME = planFlowPath.CREATE_TIME = timestamp; item.Id = Convert.ToInt32(await _database.From().Add(planFlowPath)); } } } } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.DeleteFlow 方法 */ public async Task DeleteFlow(int id) { await _database.From() .Where(f => f.FLOW_ID == id) .Update(new { FLOW_FLAG = false, UPDATE_TIME = DateTime.Now }); await _database.From() .Where(n => n.FLOW_ID == id) .Delete(); await _database.From() .Where(p => p.FLOW_ID == id) .Delete(); } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.GetNode 方法 */ public async Task GetNode(int flow, string type) { return _mapper.Map(await _database.From() .Where(n => n.FLOW_ID == flow && n.NODE_TYPE == type) .Single()); } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsSerialExist 方法 */ public async Task IsSerialExist(int id) { return (await _database.From() .Where(s => s.SERIAL_ID == id) .Single(s => new { Count = Function.Count(s.SERIAL_ID) })) .Count > 0; } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.GetSerialValue 方法 */ public async Task GetSerialValue(int id, DateTime timestamp, int timeout) { int? result = null; var guid = Guid.NewGuid().ToString("N"); var stopwatch = new Stopwatch(); stopwatch.Start(); while(!result.HasValue) { if (stopwatch.ElapsedMilliseconds >= timeout) { stopwatch.Stop(); break; } else { var serial = await _database.From() .Where(s => s.SERIAL_ID == id) .Single(); var cycle = serial.SERIAL_CYCLE; if (cycle == string.Empty) { serial.SERIAL_VALUE++; } else { cycle = timestamp.ToString("yyyyMMddHHmmss"[..cycle.Length]); if (cycle == serial.SERIAL_CYCLE) { serial.SERIAL_VALUE++; } else { serial.SERIAL_VALUE = 1; } } if(await _database.From() .Where(s => s.SERIAL_ID == id && s.SERIAL_VERSION == serial.SERIAL_VERSION) .Update(new { SERIAL_CYCLE = cycle, SERIAL_VALUE = serial.SERIAL_VALUE, SERIAL_VERSION = guid, UPDATE_TIME = DateTime.Now }) > 0) { result = serial.SERIAL_VALUE; stopwatch.Stop(); break; } } } return result; } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.CreateSerial 方法 */ public async Task CreateSerial(int id, string cycle) { var timestamp = DateTime.Now; await _database.From().Add(new() { SERIAL_ID = id, SERIAL_CYCLE = cycle, SERIAL_VALUE = 1, SERIAL_VERSION = Guid.NewGuid().ToString("N"), CREATE_TIME= timestamp, UPDATE_TIME= timestamp }); } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsOrderExist 方法 */ public async Task IsOrderExist(int id) { return (await _database.From() .Where(p => p.PLAN_ID == id) .Single(p => new { Count = Function.Count(p.PLAN_ID) })) .Count > 0; } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.IsOrderExist 方法 */ public async Task IsOrderExist(string no) { return (await _database.From() .Where(p => p.PLAN_CODE == no) .Single(p => new { Count = Function.Count(p.PLAN_ID) })) .Count > 0; } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.CreateOrder 方法 */ public async Task CreateOrder(Domain.Order.Models.Order order) { var timestamp = DateTime.Now; var planMain = _mapper.Map(order); planMain.CREATE_TIME = timestamp; planMain.UPDATE_TIME = timestamp; await _database.From().Add(planMain); foreach (var item in order.Lines) { var planList = _mapper.Map(item); planList.PLAN_ID = planMain.PLAN_ID; planList.CREATE_TIME = timestamp; planList.UPDATE_TIME = timestamp; item.Id = Convert.ToInt32(await _database.From().Add(planList)); } return planMain.PLAN_ID; } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.ModifyOrder 方法 */ public async Task ModifyOrder(int id, IEnumerable lines) { var timestamp = DateTime.Now; var planLists = (await _database.From() .Where(p => p.PLAN_ID == id) .Select()) .ToDictionary(e => e.PLAN_LIST_ID, e => e); foreach (var item in lines) { if (item.Id == 0) { var planList = _mapper.Map(item); planList.PLAN_ID = id; planList.CREATE_TIME = timestamp; planList.UPDATE_TIME = timestamp; item.Id = Convert.ToInt32(await _database.From().Add(planList)); } else { if (!planLists.ContainsKey(item.Id)) { throw new RepositoryException("订单行不存在", new(nameof(item.Id), item.Id)); } var planList = planLists[item.Id]; if (planList.ORDERED_QUANTITY > 0 || planList.FINISHED_QUANTITY > 0) { throw new RepositoryException("已执行的订单行不允许修改", new(nameof(item.Id), item.Id)); } planLists.Remove(item.Id); planList = _mapper.Map(item); planList.PLAN_ID = id; planList.UPDATE_TIME = timestamp; await _database.From().Update(planList, nameof(T_PLAN_LIST.CREATE_TIME)); } } foreach (var item in planLists.Values) { if (item.ORDERED_QUANTITY > 0 || item.FINISHED_QUANTITY > 0) { throw new RepositoryException("已执行的订单行不允许删除", new(nameof(OrderLine.Id), item.PLAN_LIST_ID)); } await _database.From().Delete(item); } } /* * 实现 Kean.Domain.Order.Repositories.IOrderRepository.DeleteOrder 方法 */ public async Task DeleteOrder(int id) { await _database.From().Where(p => p.PLAN_ID == id).Delete(); await _database.From().Where(p => p.PLAN_ID == id).Delete(); } } }