namespace Admin.NET.Plugin.AiDOP.WorkOrder; /// /// 工单下达服务 🏭 /// 路由前缀:/api/WorkOrder/dispatch/... /// [ApiDescriptionSettings(Order = 260, Description = "工单下达")] [Route("api/WorkOrder")] [AllowAnonymous] [NonUnify] public class WorkOrderDispatchService : IDynamicApiController, ITransient { private readonly ISqlSugarClient _db; private readonly UserManager _userManager; public WorkOrderDispatchService(ISqlSugarClient db, UserManager userManager) { _db = db; _userManager = userManager; } // ══════════════════════════════════════════════════════════════ // 列表 GET /api/WorkOrder/dispatch/list // ══════════════════════════════════════════════════════════════ /// 获取工单下达分页列表 🏭 [DisplayName("获取工单下达列表")] [HttpGet("dispatch/list")] public async Task GetDispatchList([FromQuery] WorkOrderDispatchListInput input) { var pars = new List(); var conditions = new List { "a.Status = 'p'" }; if (!string.IsNullOrWhiteSpace(input.WorkOrd)) { conditions.Add("a.WorkOrd LIKE @WorkOrd"); pars.Add(new SugarParameter("@WorkOrd", $"%{input.WorkOrd.Trim()}%")); } if (!string.IsNullOrWhiteSpace(input.ItemNum)) { conditions.Add("a.ItemNum LIKE @ItemNum"); pars.Add(new SugarParameter("@ItemNum", $"%{input.ItemNum.Trim()}%")); } if (!string.IsNullOrWhiteSpace(input.Descr)) { conditions.Add("b.Descr LIKE @Descr"); pars.Add(new SugarParameter("@Descr", $"%{input.Descr.Trim()}%")); } if (!string.IsNullOrWhiteSpace(input.OrdDateFrom)) { conditions.Add("a.OrdDate >= @OrdDateFrom"); pars.Add(new SugarParameter("@OrdDateFrom", input.OrdDateFrom.Trim())); } var whereClause = "WHERE " + string.Join(" AND ", conditions); var baseSql = $""" SELECT a.RecID AS Id, a.Domain, a.WorkOrd, a.Priority, a.ItemNum, b.Descr, b.Descr1, a.QtyOrded, m.MaterialSituation, a.OrdDate, a.DueDate, LOWER(a.Status) AS Status, a.LotSerial, IFNULL(nm.Nbr,'') AS PrevNbr, IFNULL(nm1.Nbr,'') AS Nbr, CONCAT(IFNULL(b.ItemNum,''), IFNULL(b.Descr,''), IFNULL(b.Descr1,'')) AS Wl FROM WorkOrdMaster a LEFT JOIN ItemMaster b ON a.ItemNum = b.ItemNum LEFT JOIN mes_morder m ON a.WorkOrd = m.morder_no AND a.Domain = m.factory_id LEFT JOIN NbrMaster nm ON a.Domain = nm.Domain AND a.WorkOrd = nm.WorkOrd AND nm.Type = 'SM' AND nm.TransType = 'PrevProcess' LEFT JOIN NbrMaster nm1 ON a.Domain = nm1.Domain AND a.WorkOrd = nm1.WorkOrd AND nm1.Type = 'SM' AND nm1.TransType = '' {whereClause} """; var offset = (input.Page - 1) * input.PageSize; var total = await _db.Ado.GetIntAsync( $"SELECT COUNT(*) FROM ({baseSql}) AS t", pars); var list = await _db.Ado.SqlQueryAsync( $"SELECT * FROM ({baseSql}) AS t ORDER BY t.Id DESC LIMIT {input.PageSize} OFFSET {offset}", pars); return new { total, page = input.Page, pageSize = input.PageSize, list }; } // ══════════════════════════════════════════════════════════════ // 工单下达 POST /api/WorkOrder/dispatch/release // ══════════════════════════════════════════════════════════════ /// 工单下达(更新开工日期、生产批号,状态改为 r)🏭 [DisplayName("工单下达")] [ApiDescriptionSettings(Name = "ReleaseWorkOrder"), HttpPost("dispatch/release")] public async Task ReleaseWorkOrder([FromBody] WorkOrderReleaseInput input) { // 参照 SysJobService.UpdateJobDetail:先查再改 var pars = new List { new SugarParameter("@WorkOrd", input.WorkOrd), new SugarParameter("@Domain", input.Domain) }; var exists = await _db.Ado.GetIntAsync( "SELECT COUNT(*) FROM WorkOrdMaster WHERE WorkOrd = @WorkOrd AND Domain = @Domain AND Status = 'p'", pars); if (exists == 0) throw Oops.Oh("工单不存在或状态不为初始(p),无法下达"); var ordDate = string.IsNullOrWhiteSpace(input.OrdDate) ? (DateTime?)null : DateTime.Parse(input.OrdDate); var releaseDate = DateTime.Now; var account = _userManager.Account ?? "system"; var updatePars = new List { new SugarParameter("@Status", "r"), new SugarParameter("@OrdDate", ordDate), new SugarParameter("@LotSerial", input.LotSerial ?? (object)DBNull.Value), new SugarParameter("@ReleaseDate", releaseDate), new SugarParameter("@UpdateUser", account), new SugarParameter("@UpdateTime", releaseDate), new SugarParameter("@WorkOrd", input.WorkOrd), new SugarParameter("@Domain", input.Domain) }; await _db.Ado.ExecuteCommandAsync( """ UPDATE WorkOrdMaster SET Status = @Status, OrdDate = @OrdDate, LotSerial = @LotSerial, ReleaseDate = @ReleaseDate, UpdateUser = @UpdateUser, UpdateTime = @UpdateTime WHERE WorkOrd = @WorkOrd AND Domain = @Domain """, updatePars); return new { message = "工单下达成功" }; } // ──────────────── 内部查询结果映射类 ──────────────── private sealed class WorkOrderDispatchRow { public int Id { get; set; } public string? Domain { get; set; } public string? WorkOrd { get; set; } public string? Priority { get; set; } public string? ItemNum { get; set; } public string? Descr { get; set; } public string? Descr1 { get; set; } public decimal? QtyOrded { get; set; } public string? MaterialSituation { get; set; } public DateTime? OrdDate { get; set; } public DateTime? DueDate { get; set; } public string? Status { get; set; } public string? LotSerial { get; set; } public string? PrevNbr { get; set; } public string? Nbr { get; set; } public string? Wl { get; set; } } }