From 4718d79b98b135e9f07c0c201386a50f3c131171 Mon Sep 17 00:00:00 2001
From: yl <ykxkd@outlook.com>
Date: 星期三, 19 十一月 2025 17:01:38 +0800
Subject: [PATCH] 增加App生产管理中报工接口

---
 VueWebCoreApi/ApiGroup/OpenApiGroup.cs              |    4 
 VueWebCoreApi/Controllers/AppProductController.cs   |   65 +++++++++
 VueWebCoreApi/DLL/BLL/AppProductBLL.cs              |   27 +++
 VueWebCoreApi/DLL/DAL/AppProductDAL.cs              |  321 +++++++++++++++++++++++++++++++++++++++++++++
 VueWebCoreApi/Controllers/AppAnalyticsController.cs |    2 
 5 files changed, 417 insertions(+), 2 deletions(-)

diff --git a/VueWebCoreApi/ApiGroup/OpenApiGroup.cs b/VueWebCoreApi/ApiGroup/OpenApiGroup.cs
index e96f137..512d12e 100644
--- a/VueWebCoreApi/ApiGroup/OpenApiGroup.cs
+++ b/VueWebCoreApi/ApiGroup/OpenApiGroup.cs
@@ -53,7 +53,9 @@
         [Description("App瀹夌伅绠$悊")]
         App瀹夌伅绠$悊 = 22,
         [Description("SOP绠$悊")]
-        SOP绠$悊 = 23
+        SOP绠$悊 = 23,
+        [Description("App鐢熶骇绠$悊")]
+        App鐢熶骇绠$悊 = 24
 
     }
 }
diff --git a/VueWebCoreApi/Controllers/AppAnalyticsController.cs b/VueWebCoreApi/Controllers/AppAnalyticsController.cs
index f45bad9..a106267 100644
--- a/VueWebCoreApi/Controllers/AppAnalyticsController.cs
+++ b/VueWebCoreApi/Controllers/AppAnalyticsController.cs
@@ -56,7 +56,7 @@
         public JsonResult ProductionScheduleKanban(string ordertype, string partcode = null, string Ratetime = null)
         {
             var token = HttpContext.Request.Headers["Token"].ToString();
-            //var token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyY29kZSI6Ijk5OCIsInVzZXJuYW1lIjoi5rWL6K-V6LSm5Y-3MSIsInN0b3JnX2NvZGUiOiJTQ0IwMV8xXzEiLCJzdG9yZ19uYW1lIjoi57K-5bel6L2m6Ze0IiwiaXNfc3lzdGVtX2FkbWluIjoiTiIsInJvbGVfY29kZSI6Ijk5OTkiLCJyb2xlX2RhdGFwZXJtaXNzaW9ucyI6IiIsInVzZXJ0eXBlIjoiQVBQIiwicmVkaXNrZXkiOiJOZXdNRVNMb2dpblVzZXJJREFQUDk5OCIsInRpbWVvdXQiOiIyMDIzLTEyLTA3VDE0OjU0OjAzLjU0NDMxMjMrMDg6MDAifQ._L0xdKgeD_dgnedzV8EEN6y2Xad0J7beswuIcNj4OKs";
+            //var token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyY29kZSI6Ijk5OSIsInVzZXJuYW1lIjoiOTk5Iiwic3RvcmdfY29kZSI6IjEiLCJzdG9yZ19uYW1lIjoi5rWZ5rGf5LyY5q2l5L2T6IKy55So5ZOB6IKh5Lu95pyJ6ZmQ5YWs5Y-4IiwiaXNfc3lzdGVtX2FkbWluIjoiTiIsInJvbGVfY29kZSI6Ijg4ODgsOTk5OSIsInJvbGVfZGF0YXBlcm1pc3Npb25zIjoiIiwidXNlcnR5cGUiOiJBUFAiLCJyZWRpc2tleSI6Ik5ld1lCTUVTTG9naW5Vc2VySURBUFA5OTkiLCJtZXNTZXR0aW5nIjoie1wicm91dGVcIjp0cnVlLFwiaXNPcmRlclwiOnRydWUsXCJkZXZpY2VcIjp0cnVlLFwidGVjaFwiOnRydWUsXCJ3b3JrT3JkZXJcIjp0cnVlLFwiZXZlcnlcIjpmYWxzZSxcImxhc3RcIjpmYWxzZX0iLCJ0aW1lb3V0IjoiMjAyNS0xMS0xOVQxMToyMzo1OS42NzgzNDQ2KzA4OjAwIn0._W55Y9dnnuOnIY5DgWgY5ZI-Xqu90HWxCwdU6T1HxZU";
             User us = JwtTools.Denocode(token.ToString());
             string startopendate = "";  //寮�濮嬫椂闂�
             string endclosedate = "";    //缁撴潫鏃堕棿
diff --git a/VueWebCoreApi/Controllers/AppProductController.cs b/VueWebCoreApi/Controllers/AppProductController.cs
new file mode 100644
index 0000000..c3b7da5
--- /dev/null
+++ b/VueWebCoreApi/Controllers/AppProductController.cs
@@ -0,0 +1,65 @@
+锘縰sing Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using VueWebCoreApi.DLL.BLL;
+using VueWebCoreApi.Models;
+using VueWebCoreApi.Tools;
+
+namespace VueWebCoreApi.Controllers
+{
+    [ApiExplorerSettings(GroupName = "App鐢熶骇绠$悊")]
+    [ApiController]
+    [Route("api/[controller]")]
+    public class AppProductController : Controller
+    {
+        //瀹氫箟鍏ㄥ眬淇℃伅杩斿洖鍙橀噺
+        ToMessage mes = new ToMessage();
+        RedisCommon redis = new RedisCommon();
+
+        #region[App宸叉淳鍙戝伐鍗曠殑鐗╂枡]
+        /// <summary>
+        /// App宸叉淳鍙戝伐鍗曠殑鐗╂枡
+        /// </summary>
+        /// <returns></returns>
+        [Route(template: "DistrInventory")]
+        [HttpGet]
+        public JsonResult DistrInventory()
+        {
+            var token = HttpContext.Request.Headers["Token"].ToString();
+            User us = JwtTools.Denocode(token.ToString());
+            mes = AppProductBLL.DistrInventory(us);
+            return Json(mes);
+        }
+        #endregion
+
+        #region[App鏌ョ湅鍗曟嵁鍙婂伐鑹轰俊鎭痌
+        /// <summary>
+        /// App鏌ョ湅鍗曟嵁鍙婂伐鑹轰俊鎭�
+        /// </summary>
+        /// <param name="ordertype">鍗曟嵁绫诲瀷(SO:閿�鍞鍗曘�丮O:鐢熶骇璁㈠崟銆丳O:鐢熶骇宸ュ崟)</param>
+        /// <param name="ordercode">鍗曟嵁缂栧彿</param>
+        /// <param name="partcode">浜у搧淇℃伅(鍙涓�)</param>
+        /// <param name="Ratetime">鍗曟嵁鏃ユ湡鑼冨洿</param>
+        /// <returns></returns>
+        [Route(template: "ProductOrderSearch")]
+        [HttpGet]
+        public JsonResult ProductOrderSearch(string ordertype,string ordercode=null, string partcode = null, string Ratetime = null)
+        {
+            var token = HttpContext.Request.Headers["Token"].ToString();
+            //var token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyY29kZSI6Ijk5OSIsInVzZXJuYW1lIjoiOTk5Iiwic3RvcmdfY29kZSI6IjEiLCJzdG9yZ19uYW1lIjoi5rWZ5rGf5LyY5q2l5L2T6IKy55So5ZOB6IKh5Lu95pyJ6ZmQ5YWs5Y-4IiwiaXNfc3lzdGVtX2FkbWluIjoiTiIsInJvbGVfY29kZSI6Ijg4ODgsOTk5OSIsInJvbGVfZGF0YXBlcm1pc3Npb25zIjoiIiwidXNlcnR5cGUiOiJBUFAiLCJyZWRpc2tleSI6Ik5ld1lCTUVTTG9naW5Vc2VySURBUFA5OTkiLCJtZXNTZXR0aW5nIjoie1wicm91dGVcIjp0cnVlLFwiaXNPcmRlclwiOnRydWUsXCJkZXZpY2VcIjp0cnVlLFwidGVjaFwiOnRydWUsXCJ3b3JrT3JkZXJcIjp0cnVlLFwiZXZlcnlcIjpmYWxzZSxcImxhc3RcIjpmYWxzZX0iLCJ0aW1lb3V0IjoiMjAyNS0xMS0xOVQxMToyMzo1OS42NzgzNDQ2KzA4OjAwIn0._W55Y9dnnuOnIY5DgWgY5ZI-Xqu90HWxCwdU6T1HxZU";
+            User us = JwtTools.Denocode(token.ToString());
+            string startopendate = "";  //寮�濮嬫椂闂�
+            string endclosedate = "";    //缁撴潫鏃堕棿
+            if (Ratetime != "" && Ratetime != null)
+            {
+                startopendate = Ratetime.Split('~')[0].ToString();
+                endclosedate = Ratetime.Split('~')[1].ToString();
+            }
+            mes = AppProductBLL.ProductOrderSearch(us, ordertype, ordercode, partcode, startopendate, endclosedate);
+            return Json(mes);
+        }
+        #endregion
+    }
+}
diff --git a/VueWebCoreApi/DLL/BLL/AppProductBLL.cs b/VueWebCoreApi/DLL/BLL/AppProductBLL.cs
new file mode 100644
index 0000000..410e206
--- /dev/null
+++ b/VueWebCoreApi/DLL/BLL/AppProductBLL.cs
@@ -0,0 +1,27 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using VueWebCoreApi.DLL.DAL;
+using VueWebCoreApi.Models;
+using VueWebCoreApi.Tools;
+
+namespace VueWebCoreApi.DLL.BLL
+{
+    public class AppProductBLL
+    {
+        #region[App宸叉淳鍙戝伐鍗曠殑鐗╂枡]
+        public static ToMessage DistrInventory(User us)
+        {
+            return AppProductDAL.DistrInventory(us);
+        }
+        #endregion
+
+        #region[App鏌ョ湅鍗曟嵁鍙婂伐鑹轰俊鎭痌
+        public static ToMessage ProductOrderSearch(User us, string ordertype,string ordercode, string partcode, string startopendate, string endclosedate)
+        {
+            return AppProductDAL.ProductOrderSearch(us, ordertype, ordercode, partcode, startopendate, endclosedate);
+        }
+        #endregion
+    }
+}
diff --git a/VueWebCoreApi/DLL/DAL/AppProductDAL.cs b/VueWebCoreApi/DLL/DAL/AppProductDAL.cs
new file mode 100644
index 0000000..ca1b06c
--- /dev/null
+++ b/VueWebCoreApi/DLL/DAL/AppProductDAL.cs
@@ -0,0 +1,321 @@
+锘縰sing Dapper;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Data.SqlClient;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using VueWebCoreApi.Models;
+using VueWebCoreApi.Tools;
+
+namespace VueWebCoreApi.DLL.DAL
+{
+    public class AppProductDAL
+    {
+        public static DataTable dt;    //瀹氫箟鍏ㄥ眬鍙橀噺dt
+        public static bool res;       //瀹氫箟鍏ㄥ眬鍙橀噺dt
+
+        public static ToMessage mes = new ToMessage(); //瀹氫箟鍏ㄥ眬杩斿洖淇℃伅瀵硅薄
+        public static string strProcName = ""; //瀹氫箟鍏ㄥ眬sql鍙橀噺
+        public static List<SqlParameter> listStr = new List<SqlParameter>(); //瀹氫箟鍏ㄥ眬鍙傛暟闆嗗悎
+        public static SqlParameter[] parameters; //瀹氫箟鍏ㄥ眬SqlParameter鍙傛暟鏁扮粍
+
+        #region[App宸叉淳鍙戝伐鍗曠殑鐗╂枡]
+        public static ToMessage DistrInventory(User us)
+        {
+            var sql = "";
+            var dynamicParams = new DynamicParameters();
+            try
+            {
+                sql = @"select distinct  P.materiel_code as code,M.partname as name   from TK_Wrk_Man P
+                      left join TMateriel_Info M  on P.materiel_code=M.partcode 
+                      where P.status<>'NEW'";
+                var data = DapperHelper.selectdata(sql, dynamicParams);
+                mes.code = "200";
+                mes.message = "鏌ヨ鎴愬姛!";
+                mes.data = data;
+            }
+            catch (Exception e)
+            {
+                mes.code = "300";
+                mes.count = 0;
+                mes.message = e.Message;
+                mes.data = null;
+            }
+            return mes;
+        }
+        #endregion
+
+        #region[App鏌ョ湅鍗曟嵁鍙婂伐鑹轰俊鎭痌
+        public static ToMessage ProductOrderSearch(User us, string ordertype, string ordercode, string partcode, string startopendate, string endclosedate)
+        {
+            Dictionary<object, object> dList = new Dictionary<object, object>();
+            var dynamicParams = new DynamicParameters();
+            string search = "",sql = "", torg_codelist = "";
+            DataTable dt;
+            try
+            {
+                //鑾峰彇褰撳墠鐢ㄦ埛鎵�灞炵粍缁囧強鎵�鏈夊瓙鑺傜偣缁勭粐
+                mes = TOrganizationRecursion.TOrgCodeSeachNo(us.storg_code);
+                if (mes.code == "300")
+                {
+                    return mes;
+                }
+                else
+                {
+                    torg_codelist = mes.data.ToString(); //鑾峰彇缁勭粐闆嗗悎
+                    string[] torglist = Array.ConvertAll<string, string>(torg_codelist.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries), s => s.ToString()); //string鍒嗗壊杞瑂tring[] 
+                    search += " and A.wkshp_code in @wkshp_code ";
+                    dynamicParams.Add("@wkshp_code", torglist.ToArray());
+                }
+                
+                //鏍规嵁鏌ヨ鏉′欢,鏌ユ壘绗﹀悎瑕佹眰鐨勫崟鎹�
+                switch (ordertype)
+                {
+                    case "SO": //鎸夐攢鍞鍗曠粺璁�
+                        if (!string.IsNullOrEmpty(ordercode))
+                        {
+                            search += "and A.saleOrderCode like '%'+@ordercode+'%' ";
+                            dynamicParams.Add("@ordercode", ordercode);
+                        }
+                        if (!string.IsNullOrEmpty(partcode))
+                        {
+                            string[] selects = Array.ConvertAll<string, string>(partcode.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries), s => s.ToString()); //string鍒嗗壊杞瑂tring[] 
+                            search += " and A.materiel_code in @partcode ";
+                            dynamicParams.Add("@partcode", selects.ToArray());
+                        }
+                        if (!string.IsNullOrEmpty(startopendate))
+                        {
+                            search += " and convert(varchar(100),A.lm_date,21)>=@startopendate and convert(varchar(100),A.lm_date,21)<=@endclosedate ";
+                            dynamicParams.Add("@startopendate", startopendate + " 00:00:00");
+                            dynamicParams.Add("@endclosedate", endclosedate + " 23:59:59");
+                        }
+                        //鑾峰彇鍗曟嵁淇℃伅
+                        sql = @"select distinct BB.wo_code as ordercode,BB.materiel_code as partcode,P.partname,P.partspec,E.saleOrderDate as lm_date,sum(BB.plan_qty) as orderqty   
+                                from TKimp_Ewo E
+                                inner join(
+                                  select A.m_po,A.wo_code,A.plan_qty,A.materiel_code
+                                  from TK_Wrk_Man A
+                                  where A.status not in('NEW','CLOSED') " + search + ") as BB on E.wo=BB.m_po and E.materiel_code=BB.materiel_code left join TMateriel_Info P on E.materiel_code=p.partcode group by BB.wo_code,BB.materiel_code,P.partname,P.partspec,E.saleOrderDate  order by E.saleOrderDate desc";
+                        var sorders = DapperHelper.select<AppScheduleKanban>(sql, dynamicParams).AsList();
+                        if (sorders.Count == 0)
+                        {
+                            mes.code = "300";
+                            mes.count = 0;
+                            mes.message = "鏃犵鍚堣姹傚崟鎹紒";
+                            mes.data = null;
+                            return mes;
+                        }
+                        // 鎵归噺鏌ヨ鎵�鏈夊伐鍗曠殑姝ラ淇℃伅
+                        var soCodes = sorders.Select(o => o.ordercode).Distinct().ToArray();
+                        sql = @"select M.wo_code,T.stepcode,T.stepname,S.plan_qty,S.good_qty,S.isend   
+                                        from TK_Wrk_Man M
+                                        inner join TK_Wrk_Step S on M.wo_code=S.wo_code 
+                                        left  join TStep T on S.step_code=T.stepcode
+                                        where  M.wo_code in @wo_codes
+                                        order by M.wo_code,S.seq ";
+                        dynamicParams.Add("@wo_codes", soCodes);
+                        var sosteps = DapperHelper.select<StepResult>(sql, dynamicParams);
+                        var stepsBySoCode = sosteps.GroupBy(s => s.wo_code).ToDictionary(g => g.Key, g => g.AsEnumerable());
+                        // 缁勮鏁版嵁
+                        foreach (var order in sorders)
+                        {
+                            if (stepsBySoCode.TryGetValue(order.ordercode, out var orderSteps))
+                            {
+                                order.children = orderSteps.Select(s => new AppScheduleKanbanSub
+                                {
+                                    code = s.stepcode,
+                                    name = s.stepname,
+                                    spec = s.isend,
+                                    planqty = s.plan_qty.ToString("F2"),
+                                    goodqty = s.good_qty.ToString("F2")
+                                }).ToList();
+
+                                var endStep = orderSteps.FirstOrDefault(s => s.isend == "Y");
+                                order.ordergoodqty = endStep?.good_qty.ToString("F2") ?? "0";
+                            }
+                            else
+                            {
+                                order.children = new List<AppScheduleKanbanSub>();
+                                order.ordergoodqty = "0";
+                            }
+                        }
+                        mes.code = "200";
+                        mes.count = sorders.Count;
+                        mes.data = sorders;
+                        mes.message = "鏌ヨ鎴愬姛!";
+                        break;
+                    case "MO": //鎸夌敓浜ц鍗曠粺璁�
+                        if (!string.IsNullOrEmpty(ordercode))
+                        {
+                            search += "and A.m_po like '%'+@ordercode+'%' ";
+                            dynamicParams.Add("@ordercode", ordercode);
+                        }
+                        if (!string.IsNullOrEmpty(partcode))
+                        {
+                            string[] selects = Array.ConvertAll<string, string>(partcode.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries), s => s.ToString()); //string鍒嗗壊杞瑂tring[] 
+                            search += " and A.materiel_code in @partcode ";
+                            dynamicParams.Add("@partcode", selects.ToArray());
+                        }
+                        if (!string.IsNullOrEmpty(startopendate))
+                        {
+                            search += " and convert(varchar(100),A.lm_date,21)>=@startopendate and convert(varchar(100),A.lm_date,21)<=@endclosedate ";
+                            dynamicParams.Add("@startopendate", startopendate + " 00:00:00");
+                            dynamicParams.Add("@endclosedate", endclosedate + " 23:59:59");
+                        }
+                        //鑾峰彇鍗曟嵁淇℃伅
+                        sql = @"select distinct BB.wo_code as ordercode,BB.materiel_code as partcode,P.partname,P.partspec,E.voucherdate as lm_date,sum(BB.plan_qty) as orderqty   
+                                from TKimp_Ewo E
+                                inner join(
+                                  select A.m_po,A.wo_code,A.plan_qty,A.materiel_code
+                                  from TK_Wrk_Man A
+                                  where A.status not in('NEW','CLOSED') " + search + ") as BB on E.wo=BB.m_po and E.materiel_code=BB.materiel_code left join TMateriel_Info P on E.materiel_code=p.partcode group by BB.wo_code,BB.materiel_code,P.partname,P.partspec,E.voucherdate  order by E.voucherdate desc";
+                        var morders = DapperHelper.select<AppScheduleKanban>(sql, dynamicParams).AsList();
+                        if (morders.Count == 0)
+                        {
+                            mes.code = "300";
+                            mes.count = 0;
+                            mes.message = "鏃犵鍚堣姹傚崟鎹紒";
+                            mes.data = null;
+                            return mes;
+                        }
+                        // 鎵归噺鏌ヨ鎵�鏈夊伐鍗曠殑姝ラ淇℃伅
+                        var moCodes = morders.Select(o => o.ordercode).Distinct().ToArray();
+                        sql = @"select M.wo_code,T.stepcode,T.stepname,S.plan_qty,S.good_qty,S.isend   
+                                        from TK_Wrk_Man M
+                                        inner join TK_Wrk_Step S on M.wo_code=S.wo_code 
+                                        left  join TStep T on S.step_code=T.stepcode
+                                        where  M.wo_code in @wo_codes
+                                        order by M.wo_code,S.seq ";
+                        dynamicParams.Add("@wo_codes", moCodes);
+                        var mosteps = DapperHelper.select<StepResult>(sql, dynamicParams);
+                        var stepsByMoCode = mosteps.GroupBy(s => s.wo_code).ToDictionary(g => g.Key, g => g.AsEnumerable());
+                        // 缁勮鏁版嵁
+                        foreach (var order in morders)
+                        {
+                            if (stepsByMoCode.TryGetValue(order.ordercode, out var orderSteps))
+                            {
+                                order.children = orderSteps.Select(s => new AppScheduleKanbanSub
+                                {
+                                    code = s.stepcode,
+                                    name = s.stepname,
+                                    spec = s.isend,
+                                    planqty = s.plan_qty.ToString("F2"),
+                                    goodqty = s.good_qty.ToString("F2")
+                                }).ToList();
+
+                                var endStep = orderSteps.FirstOrDefault(s => s.isend == "Y");
+                                order.ordergoodqty = endStep?.good_qty.ToString("F2") ?? "0";
+                            }
+                            else
+                            {
+                                order.children = new List<AppScheduleKanbanSub>();
+                                order.ordergoodqty = "0";
+                            }
+                        }
+                        mes.code = "200";
+                        mes.count = morders.Count;
+                        mes.data = morders;
+                        mes.message = "鏌ヨ鎴愬姛!";
+                        break;
+                    case "PO": //鎸夌敓浜у伐鍗曠粺璁�
+                        if (!string.IsNullOrEmpty(ordercode))
+                        {
+                            search += "and A.wo_code like '%'+@ordercode+'%' ";
+                            dynamicParams.Add("@ordercode", ordercode);
+                        }
+                        if (!string.IsNullOrEmpty(partcode))
+                        {
+                            string[] selects = Array.ConvertAll<string, string>(partcode.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries), s => s.ToString()); //string鍒嗗壊杞瑂tring[] 
+                            search += " and A.materiel_code in @partcode ";
+                            dynamicParams.Add("@partcode", selects.ToArray());
+                        }
+                        if (!string.IsNullOrEmpty(startopendate))
+                        {
+                            search += " and convert(varchar(100),A.lm_date,21)>=@startopendate and convert(varchar(100),A.lm_date,21)<=@endclosedate ";
+                            dynamicParams.Add("@startopendate", startopendate + " 00:00:00");
+                            dynamicParams.Add("@endclosedate", endclosedate + " 23:59:59");
+                        }
+                        //鑾峰彇鍗曟嵁淇℃伅
+                        sql = @"select distinct A.wo_code as ordercode,T.partcode,T.partname,T.partspec,A.lm_date,sum(A.plan_qty) as orderqty
+                                from TK_Wrk_Man A  
+                                left  join TMateriel_Info T on A.materiel_code=T.partcode
+                                where A.status<>'CLOSED' " + search+ " group by A.wo_code,T.partcode,T.partname,T.partspec,A.lm_date  order by A.lm_date desc";
+                        var orders = DapperHelper.select<AppScheduleKanban>(sql, dynamicParams).AsList();
+                        if (orders.Count == 0)
+                        {
+                            mes.code = "300";
+                            mes.count = 0;
+                            mes.message = "鏃犵鍚堣姹傚崟鎹紒";
+                            mes.data = null;
+                            return mes;
+                        }
+                        // 鎵归噺鏌ヨ鎵�鏈夊伐鍗曠殑姝ラ淇℃伅
+                        var woCodes = orders.Select(o => o.ordercode).Distinct().ToArray();
+                        sql = @"select M.wo_code,T.stepcode,T.stepname,S.plan_qty,S.good_qty,S.isend   
+                                        from TK_Wrk_Man M
+                                        inner join TK_Wrk_Step S on M.wo_code=S.wo_code 
+                                        left  join TStep T on S.step_code=T.stepcode
+                                        where  M.wo_code in @wo_codes
+                                        order by M.wo_code,S.seq ";
+                        dynamicParams.Add("@wo_codes", woCodes);
+                        var posteps =  DapperHelper.select<StepResult>(sql, dynamicParams);
+                        var stepsByWoCode = posteps.GroupBy(s => s.wo_code).ToDictionary(g => g.Key, g => g.AsEnumerable());
+                        // 缁勮鏁版嵁
+                        foreach (var order in orders)
+                        {
+                            if (stepsByWoCode.TryGetValue(order.ordercode, out var orderSteps))
+                            {
+                                order.children = orderSteps.Select(s => new AppScheduleKanbanSub
+                                {
+                                    code = s.stepcode,
+                                    name = s.stepname,
+                                    spec = s.isend,
+                                    planqty = s.plan_qty.ToString("F2"),
+                                    goodqty = s.good_qty.ToString("F2")
+                                }).ToList();
+
+                                var endStep = orderSteps.FirstOrDefault(s => s.isend == "Y");
+                                order.ordergoodqty = endStep?.good_qty.ToString("F2") ?? "0";
+                            }
+                            else
+                            {
+                                order.children = new List<AppScheduleKanbanSub>();
+                                order.ordergoodqty = "0";
+                            }
+                        }
+                        mes.code = "200";
+                        mes.count = orders.Count;
+                        mes.data = orders;
+                        mes.message = "鏌ヨ鎴愬姛!";
+                        break;
+                    default:
+                        break;
+                }
+            }
+            catch (Exception e)
+            {
+                mes.code = "300";
+                mes.count = 0;
+                mes.message = e.Message;
+                mes.data = null;
+            }
+            return mes;
+        }
+        #endregion
+
+        #region[姝ラ鏌ヨ缁撴灉鏄犲皠绫籡
+        // 姝ラ鏌ヨ缁撴灉鏄犲皠绫�
+        private class StepResult
+        {
+            public string wo_code { get; set; }
+            public string stepcode { get; set; }
+            public string stepname { get; set; }
+            public decimal plan_qty { get; set; }
+            public decimal good_qty { get; set; }
+            public string isend { get; set; }
+        }
+        #endregion
+    }
+}

--
Gitblit v1.9.3