From 1399b9a80a289c85c9cb7703b1368a0116309292 Mon Sep 17 00:00:00 2001 From: zhangxinyang Date: Tue, 30 Jun 2026 17:41:40 +0800 Subject: [PATCH] feat: update MES tracking and reporting workflows --- ...ct_pass_rate_workstation_menu_20260630.sql | 147 ++++++ ...product_pass_rate_workstation_20260630.sql | 172 +++++++ ...lan_order_close_no_work_hours_20260630.sql | 188 ++++++++ ...kit_tracking_result_inventory_20260630.sql | 409 ++++++++++++++++ ...ng_result_multi_detail_orders_20260630.sql | 423 ++++++++++++++++ ...racking_result_purchase_order_20260630.sql | 418 ++++++++++++++++ doc/新增产品合格率.docx | Bin 0 -> 20326 bytes doc/设计报工任务模块.docx | Bin 0 -> 42889 bytes gptlog-process/gpdlog.md | 452 ++++++++++++++++++ .../TimelyKitTrackingResult/index.vue | 169 ++++--- .../ProductPassRateWorkstation/index.vue | 283 +++++++++++ .../CheckTask/processReceive.vue | 71 +-- .../PlannOrderClose/01-项目功能内容.md | 26 + .../02-项目程序开发详细步骤.md | 44 ++ .../PlannOrderClose/03-推进台账.md | 46 ++ .../PlannOrderClose/04-任务矩阵.md | 11 + .../PlannOrderClose/05-验收证据.md | 74 +++ .../PlannOrderClose/06-决策记录.md | 20 + work/PlanManagement/PlannOrderClose/README.md | 18 + .../01-项目功能内容.md | 12 + .../02-项目程序开发详细步骤.md | 10 + .../TimelyKitTrackingResult/03-推进台账.md | 143 ++++++ .../TimelyKitTrackingResult/04-任务矩阵.md | 7 + .../TimelyKitTrackingResult/05-验收证据.md | 290 +++++++++++ .../TimelyKitTrackingResult/06-决策记录.md | 36 ++ .../TimelyKitTrackingResult/README.md | 10 + .../AGVtask/01-项目功能内容.md | 27 ++ .../AGVtask/02-项目程序开发详细步骤.md | 32 ++ .../AGVtask/03-推进台账.md | 44 ++ .../AGVtask/04-任务矩阵.md | 11 + .../AGVtask/05-验收证据.md | 58 +++ .../AGVtask/06-决策记录.md | 14 + work/ProductionManagement/AGVtask/README.md | 19 + .../DesignReportTask/01-项目功能内容.md | 154 ++++++ .../02-项目程序开发详细步骤.md | 55 +++ .../DesignReportTask/03-推进台账.md | 36 ++ .../DesignReportTask/04-任务矩阵.md | 14 + .../DesignReportTask/05-验收证据.md | 41 ++ .../DesignReportTask/06-决策记录.md | 54 +++ .../DesignReportTask/README.md | 17 + .../01-项目功能内容.md | 55 +++ .../02-项目程序开发详细步骤.md | 51 ++ .../ProductPassRateWorkstation/03-推进台账.md | 176 +++++++ .../ProductPassRateWorkstation/04-任务矩阵.md | 15 + .../ProductPassRateWorkstation/05-验收证据.md | 137 ++++++ .../ProductPassRateWorkstation/06-决策记录.md | 44 ++ .../ProductPassRateWorkstation/README.md | 22 + 47 files changed, 4465 insertions(+), 90 deletions(-) create mode 100644 db_backups/add_product_pass_rate_workstation_menu_20260630.sql create mode 100644 db_backups/create_product_pass_rate_workstation_20260630.sql create mode 100644 db_backups/update_plan_order_close_no_work_hours_20260630.sql create mode 100644 db_backups/update_timely_kit_tracking_result_inventory_20260630.sql create mode 100644 db_backups/update_timely_kit_tracking_result_multi_detail_orders_20260630.sql create mode 100644 db_backups/update_timely_kit_tracking_result_purchase_order_20260630.sql create mode 100644 doc/新增产品合格率.docx create mode 100644 doc/设计报工任务模块.docx create mode 100644 src/views/ProductionManagement/ProductPassRateWorkstation/index.vue create mode 100644 work/PlanManagement/PlannOrderClose/01-项目功能内容.md create mode 100644 work/PlanManagement/PlannOrderClose/02-项目程序开发详细步骤.md create mode 100644 work/PlanManagement/PlannOrderClose/03-推进台账.md create mode 100644 work/PlanManagement/PlannOrderClose/04-任务矩阵.md create mode 100644 work/PlanManagement/PlannOrderClose/05-验收证据.md create mode 100644 work/PlanManagement/PlannOrderClose/06-决策记录.md create mode 100644 work/PlanManagement/PlannOrderClose/README.md create mode 100644 work/ProductionManagement/AGVtask/01-项目功能内容.md create mode 100644 work/ProductionManagement/AGVtask/02-项目程序开发详细步骤.md create mode 100644 work/ProductionManagement/AGVtask/03-推进台账.md create mode 100644 work/ProductionManagement/AGVtask/04-任务矩阵.md create mode 100644 work/ProductionManagement/AGVtask/05-验收证据.md create mode 100644 work/ProductionManagement/AGVtask/06-决策记录.md create mode 100644 work/ProductionManagement/AGVtask/README.md create mode 100644 work/ProductionManagement/DesignReportTask/01-项目功能内容.md create mode 100644 work/ProductionManagement/DesignReportTask/02-项目程序开发详细步骤.md create mode 100644 work/ProductionManagement/DesignReportTask/03-推进台账.md create mode 100644 work/ProductionManagement/DesignReportTask/04-任务矩阵.md create mode 100644 work/ProductionManagement/DesignReportTask/05-验收证据.md create mode 100644 work/ProductionManagement/DesignReportTask/06-决策记录.md create mode 100644 work/ProductionManagement/DesignReportTask/README.md create mode 100644 work/ProductionManagement/ProductPassRateWorkstation/01-项目功能内容.md create mode 100644 work/ProductionManagement/ProductPassRateWorkstation/02-项目程序开发详细步骤.md create mode 100644 work/ProductionManagement/ProductPassRateWorkstation/03-推进台账.md create mode 100644 work/ProductionManagement/ProductPassRateWorkstation/04-任务矩阵.md create mode 100644 work/ProductionManagement/ProductPassRateWorkstation/05-验收证据.md create mode 100644 work/ProductionManagement/ProductPassRateWorkstation/06-决策记录.md create mode 100644 work/ProductionManagement/ProductPassRateWorkstation/README.md diff --git a/db_backups/add_product_pass_rate_workstation_menu_20260630.sql b/db_backups/add_product_pass_rate_workstation_menu_20260630.sql new file mode 100644 index 0000000..14b05e3 --- /dev/null +++ b/db_backups/add_product_pass_rate_workstation_menu_20260630.sql @@ -0,0 +1,147 @@ +USE [YL_MESDB] +GO + +SET NOCOUNT ON; + +DECLARE @Title nvarchar(100) = N'产品合格率(工位)'; +DECLARE @Path nvarchar(300) = N'ProductPassRateWorkstation/index'; +DECLARE @Component nvarchar(300) = N'/ProductionManagement/ProductPassRateWorkstation/index'; +DECLARE @Name nvarchar(100) = N'ProductPassRateWorkstation'; +DECLARE @SourcePath nvarchar(300) = N'ProductionPlanTrack/index'; +DECLARE @SourceComponent nvarchar(300) = N'/ProductionManagement/ProductionPlanTrack/index'; +DECLARE @TargetRole int = NULL; + +IF OBJECT_ID(N'dbo.登录基础数据_二级菜单', N'U') IS NULL +BEGIN + RAISERROR(N'未找到表 dbo.登录基础数据_二级菜单。', 16, 1); + RETURN; +END; + +DECLARE @IdIsIdentity bit = ISNULL(COLUMNPROPERTY(OBJECT_ID(N'dbo.登录基础数据_二级菜单'), N'id', 'IsIdentity'), 0); + +IF @IdIsIdentity = 1 +BEGIN + ;WITH SourceRows AS + ( + SELECT + src.[账号代码], + COALESCE(prodParent.[id], src.[pid]) AS [pid], + src.[icon], + src.[AddData], + src.[DeleteData], + src.[EditData], + src.[SearchData] + FROM [dbo].[登录基础数据_二级菜单] AS src + OUTER APPLY + ( + SELECT TOP (1) rp.[id] + FROM [dbo].[登录基础数据_二级菜单] AS rp + WHERE rp.[账号代码] = src.[账号代码] + AND rp.[是否启用] = 1 + AND rp.[title] = N'生产管理' + ORDER BY rp.[id] + ) AS prodParent + WHERE src.[是否启用] = 1 + AND (@TargetRole IS NULL OR src.[账号代码] = @TargetRole) + AND (src.[path] = @SourcePath OR src.[componet] = @SourceComponent OR src.[title] = N'生产计划跟踪') + AND NOT EXISTS + ( + SELECT 1 + FROM [dbo].[登录基础数据_二级菜单] AS existing + WHERE existing.[账号代码] = src.[账号代码] + AND (existing.[path] = @Path OR existing.[componet] = @Component OR existing.[title] = @Title) + ) + ) + INSERT INTO [dbo].[登录基础数据_二级菜单] + ([pid], [path], [componet], [redirect], [name], [title], [icon], [账号代码], [是否启用], [AddData], [DeleteData], [EditData], [SearchData]) + SELECT + [pid], + @Path, + @Component, + NULL, + @Name, + @Title, + [icon], + [账号代码], + 1, + [AddData], + [DeleteData], + [EditData], + [SearchData] + FROM SourceRows; +END +ELSE +BEGIN + ;WITH SourceRows AS + ( + SELECT + ROW_NUMBER() OVER (ORDER BY src.[账号代码], src.[id]) AS rn, + src.[账号代码], + COALESCE(prodParent.[id], src.[pid]) AS [pid], + src.[icon], + src.[AddData], + src.[DeleteData], + src.[EditData], + src.[SearchData] + FROM [dbo].[登录基础数据_二级菜单] AS src + OUTER APPLY + ( + SELECT TOP (1) rp.[id] + FROM [dbo].[登录基础数据_二级菜单] AS rp + WHERE rp.[账号代码] = src.[账号代码] + AND rp.[是否启用] = 1 + AND rp.[title] = N'生产管理' + ORDER BY rp.[id] + ) AS prodParent + WHERE src.[是否启用] = 1 + AND (@TargetRole IS NULL OR src.[账号代码] = @TargetRole) + AND (src.[path] = @SourcePath OR src.[componet] = @SourceComponent OR src.[title] = N'生产计划跟踪') + AND NOT EXISTS + ( + SELECT 1 + FROM [dbo].[登录基础数据_二级菜单] AS existing + WHERE existing.[账号代码] = src.[账号代码] + AND (existing.[path] = @Path OR existing.[componet] = @Component OR existing.[title] = @Title) + ) + ), + BaseId AS + ( + SELECT ISNULL(MAX([id]), 0) AS maxId + FROM [dbo].[登录基础数据_二级菜单] + ) + INSERT INTO [dbo].[登录基础数据_二级菜单] + ([id], [pid], [path], [componet], [redirect], [name], [title], [icon], [账号代码], [是否启用], [AddData], [DeleteData], [EditData], [SearchData]) + SELECT + BaseId.maxId + SourceRows.rn, + SourceRows.[pid], + @Path, + @Component, + NULL, + @Name, + @Title, + SourceRows.[icon], + SourceRows.[账号代码], + 1, + SourceRows.[AddData], + SourceRows.[DeleteData], + SourceRows.[EditData], + SourceRows.[SearchData] + FROM SourceRows + CROSS JOIN BaseId; +END; + +UPDATE [dbo].[登录基础数据_二级菜单] +SET + [path] = @Path, + [componet] = @Component, + [name] = @Name, + [title] = @Title, + [模块代码] = [id], + [是否启用] = 1 +WHERE [title] = @Title OR [componet] = @Component OR [path] = @Path; + +SELECT [id], [pid], [path], [componet], [name], [title], [icon], [账号代码], [是否启用], [SearchData] +FROM [dbo].[登录基础数据_二级菜单] +WHERE [path] = @Path OR [componet] = @Component OR [title] = @Title +ORDER BY [账号代码], [id]; + diff --git a/db_backups/create_product_pass_rate_workstation_20260630.sql b/db_backups/create_product_pass_rate_workstation_20260630.sql new file mode 100644 index 0000000..ae3ec7c --- /dev/null +++ b/db_backups/create_product_pass_rate_workstation_20260630.sql @@ -0,0 +1,172 @@ +USE [YL_MESDB] +GO + +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO + +IF OBJECT_ID(N'dbo.生产管理_产品合格率工位_查询', N'P') IS NULL +BEGIN + EXEC(N'CREATE PROCEDURE [dbo].[生产管理_产品合格率工位_查询] AS BEGIN SET NOCOUNT ON; END'); +END +GO + +ALTER PROCEDURE [dbo].[生产管理_产品合格率工位_查询] + @生产订单号 nvarchar(100) = N'', + @物料编码 nvarchar(200) = N'', + @物料名称 nvarchar(200) = N'', + @关闭日期_Start nvarchar(50) = N'', + @关闭日期_End nvarchar(50) = N'', + @工序 nvarchar(100) = N'', + @工位 nvarchar(100) = N'', + @合格状态 nvarchar(20) = N'不合格' +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @开始日期 date = TRY_CONVERT(date, NULLIF(@关闭日期_Start, N'')); + DECLARE @结束日期 date = TRY_CONVERT(date, NULLIF(@关闭日期_End, N'')); + + IF @开始日期 IS NULL AND @结束日期 IS NULL AND @生产订单号 = N'' + BEGIN + SET @开始日期 = DATEADD(day, -30, CONVERT(date, GETDATE())); + SET @结束日期 = CONVERT(date, GETDATE()); + END; + + CREATE TABLE #已关闭订单 + ( + [生产订单号] nvarchar(100) NOT NULL PRIMARY KEY, + [关闭日期] datetime NULL, + [物料名称] nvarchar(200) NULL, + [物料编码] nvarchar(50) NULL, + [计划数量] decimal(18, 4) NULL + ); + + DECLARE @SapSql nvarchar(max) = + N'SELECT 生产订单号, 实际结算日期, 产品名称, 产品编码, 产品计划数量, 单据状态 FROM SBO_YL.dbo.UBT_OWOR WHERE 单据状态 IS NOT NULL'; + + IF @生产订单号 <> N'' + SET @SapSql += N' AND 生产订单号 = ''' + REPLACE(@生产订单号, N'''', N'''''') + N''''; + + IF @开始日期 IS NOT NULL + SET @SapSql += N' AND 实际结算日期 >= ''' + CONVERT(nvarchar(10), @开始日期, 120) + N''''; + + IF @结束日期 IS NOT NULL + SET @SapSql += N' AND 实际结算日期 < ''' + CONVERT(nvarchar(10), DATEADD(day, 1, @结束日期), 120) + N''''; + + DECLARE @OpenQuerySql nvarchar(max) = + N'INSERT INTO #已关闭订单 + ([生产订单号], [关闭日期], [物料名称], [物料编码], [计划数量]) + SELECT CONVERT(nvarchar(100), [生产订单号]) AS [生产订单号], + [实际结算日期] AS [关闭日期], + [产品名称] AS [物料名称], + [产品编码] AS [物料编码], + CAST(ISNULL([产品计划数量], 0) AS decimal(18, 4)) AS [计划数量] + FROM OPENQUERY([SAP], ''' + REPLACE(@SapSql, N'''', N'''''') + N''') + WHERE (@物料编码 = N'''' OR [产品编码] LIKE N''%'' + @物料编码 + N''%'') + AND (@物料名称 = N'''' OR [产品名称] LIKE N''%'' + @物料名称 + N''%'')'; + + EXEC sp_executesql + @OpenQuerySql, + N'@物料编码 nvarchar(200), @物料名称 nvarchar(200)', + @物料编码 = @物料编码, + @物料名称 = @物料名称; + + CREATE TABLE #明细汇总 + ( + [生产订单号] nvarchar(100) NOT NULL, + [工序号] int NULL, + [工序] nvarchar(200) NOT NULL, + [工位] nvarchar(200) NOT NULL, + [完成数量] decimal(18, 4) NOT NULL, + [不良数量] decimal(18, 4) NOT NULL, + [合格率] decimal(18, 2) NULL, + [检测说明] nvarchar(max) NULL + ); + + ;WITH 明细基础 AS + ( + SELECT + o.[生产订单号], + COALESCE(t.[订单行号], q.[行号]) AS [工序号], + COALESCE(NULLIF(q.[工序名称], N''), NULLIF(t.[工序名称], N''), N'') AS [工序], + COALESCE(NULLIF(q.[工位名称], N''), NULLIF(t.[指派对象], N''), N'空白') AS [工位], + CAST(ISNULL(q.[检验数量], ISNULL(q.[合格数], 0) + ISNULL(q.[不合格数], 0)) AS decimal(18, 4)) AS [完成数量], + CAST(ISNULL(q.[不合格数], 0) AS decimal(18, 4)) AS [不良数量], + NULLIF(LTRIM(RTRIM(CONVERT(nvarchar(max), q.[检测说明]))), N'') AS [检测说明] + FROM #已关闭订单 AS o + INNER JOIN [dbo].[YL_质量检验_质检记录] AS q + ON CONVERT(nvarchar(100), q.[计划号]) = o.[生产订单号] + LEFT JOIN [dbo].[MES_接口_生产计划_生产任务] AS t + ON q.[TaskAID] = t.[AID] + WHERE q.[质检类型] = N'收检' + AND (@工序 = N'' OR COALESCE(NULLIF(q.[工序名称], N''), NULLIF(t.[工序名称], N''), N'') LIKE N'%' + @工序 + N'%') + AND (@工位 = N'' OR COALESCE(NULLIF(q.[工位名称], N''), NULLIF(t.[指派对象], N''), N'空白') LIKE N'%' + @工位 + N'%') + ) + INSERT INTO #明细汇总 + ([生产订单号], [工序号], [工序], [工位], [完成数量], [不良数量], [合格率], [检测说明]) + SELECT + [生产订单号], + [工序号], + [工序], + [工位], + SUM([完成数量]) AS [完成数量], + SUM([不良数量]) AS [不良数量], + CAST( + CASE + WHEN SUM([完成数量]) = 0 THEN NULL + ELSE (SUM([完成数量]) - SUM([不良数量])) * 100.0 / SUM([完成数量]) + END AS decimal(18, 2) + ) AS [合格率], + STRING_AGG(CONVERT(nvarchar(max), [检测说明]), N';') AS [检测说明] + FROM 明细基础 + GROUP BY [生产订单号], [工序号], [工序], [工位]; + + ;WITH 一级汇总 AS + ( + SELECT + [生产订单号], + SUM([完成数量]) AS [完成数量], + SUM([不良数量]) AS [不良数量], + CAST( + CASE + WHEN SUM([完成数量]) = 0 THEN NULL + ELSE (SUM([完成数量]) - SUM([不良数量])) * 100.0 / SUM([完成数量]) + END AS decimal(18, 2) + ) AS [合格率] + FROM #明细汇总 + GROUP BY [生产订单号] + ) + SELECT + o.[关闭日期], + o.[生产订单号], + o.[物料名称], + o.[物料编码], + o.[计划数量], + a.[完成数量], + a.[不良数量], + a.[合格率], + ( + SELECT + d.[工序], + d.[工序号], + d.[工位], + d.[完成数量], + d.[不良数量], + d.[合格率], + ISNULL(d.[检测说明], N'') AS [检测说明] + FROM #明细汇总 AS d + WHERE d.[生产订单号] = o.[生产订单号] + ORDER BY d.[工序号], d.[工序], d.[工位] + FOR JSON PATH + ) AS [明细JSON] + FROM #已关闭订单 AS o + INNER JOIN 一级汇总 AS a + ON o.[生产订单号] = a.[生产订单号] + WHERE (@合格状态 = N'' OR @合格状态 = N'全部' + OR (@合格状态 = N'合格' AND ISNULL(a.[合格率], 0) >= 100) + OR (@合格状态 = N'不合格' AND ISNULL(a.[合格率], 0) < 100)) + ORDER BY o.[关闭日期] DESC, TRY_CONVERT(int, o.[生产订单号]) DESC, o.[生产订单号] DESC; +END +GO diff --git a/db_backups/update_plan_order_close_no_work_hours_20260630.sql b/db_backups/update_plan_order_close_no_work_hours_20260630.sql new file mode 100644 index 0000000..f6a0e56 --- /dev/null +++ b/db_backups/update_plan_order_close_no_work_hours_20260630.sql @@ -0,0 +1,188 @@ +USE [YL_MESDB] +GO + +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO + +/* + 2026-06-30 + 生产订单关闭查询:可关闭订单补充“无工时但满足其他可关闭条件”的特殊情况。 + + 规则: + 1. 有工时订单:继续要求 View_生产工时视图 中所有工时记录已校验。 + 2. 无工时订单:必须在 MES_接口_生产计划 中存在,且 View_生产工时视图 中没有任何工时记录。 + 3. 无工时订单不做工时全部校验,但仍必须满足原有可关闭条件: + - 单据状态为空; + - 终检/收检/计划数量/入库数量满足原过程 HAVING 条件; + - 入库数量等于终检合格数。 +*/ +ALTER PROCEDURE [dbo].[计划排产_生产订单关闭_查询全部订单] + @订单号 nvarchar(100) = N'', + @单据状态 nvarchar(100) = N'', -- 可选值:'已关闭'、'未关闭'、'可关闭' + @属性 nvarchar(100) = N'' +AS +BEGIN + SET NOCOUNT ON; + + IF (@单据状态 = N'可关闭') + BEGIN + CREATE TABLE #工时订单 + ( + 订单号 nvarchar(100) NOT NULL PRIMARY KEY + ); + + INSERT INTO #工时订单 (订单号) + SELECT DISTINCT CONVERT(nvarchar(100), 订单号) + FROM dbo.View_生产工时视图 + WHERE 订单号 IS NOT NULL; + + ;WITH 收检数量 AS + ( + SELECT + 计划号, + SUM(ISNULL(合格数, 0)) AS 合格数合计, + SUM(ISNULL(不合格数, 0)) AS 不合格数合计 + FROM dbo.YL_质量检验_质检记录 + WHERE 质检类型 = N'收检' + GROUP BY 计划号 + ), + 终检数量 AS + ( + SELECT + 计划号, + SUM(ISNULL(合格数, 0)) AS 终检合格数合计, + SUM(ISNULL(不合格数, 0)) AS 终检不合格数合计 + FROM dbo.YL_质量检验_质检记录 + WHERE 质检类型 = N'终检' + GROUP BY 计划号 + ), + 可关闭订单 AS + ( + SELECT + v.订单号 AS 订单编号, + MAX(v.产品名称) AS 产品名称, + MAX(v.产品编码) AS 产品编码, + MAX(v.入库数量) AS 入库数量, + MAX(v.订单合同号) AS 合同号, + MAX(终检数量.终检不合格数合计) AS 终检不合格数合计, + MAX(终检数量.终检合格数合计) AS 终检合格数合计, + MAX(v.计划数量) AS 计划数量, + MAX(v.确认状态) AS 确认状态, + MAX(v.单据状态) AS 单据状态, + MAX(收检数量.不合格数合计) AS 不合格数合计, + MIN(CASE WHEN v.Expr1 IS NULL THEN 0 ELSE 1 END) AS 是否全部校验 + FROM dbo.View_生产工时视图 AS v + LEFT JOIN 收检数量 ON v.订单号 = 收检数量.计划号 + LEFT JOIN 终检数量 ON v.订单号 = 终检数量.计划号 + WHERE v.单据状态 IS NULL + AND (@订单号 = N'' OR v.订单号 = @订单号) + AND ( + @属性 NOT IN (N'机加', N'装配') + OR (@属性 = N'机加' AND v.自制件属性 = N'机加件') + OR (@属性 = N'装配' AND v.自制件属性 LIKE N'%装配%') + ) + GROUP BY v.订单号 + HAVING + MIN(CASE WHEN v.Expr1 IS NULL THEN 0 ELSE 1 END) = 1 + AND ( + MAX(终检数量.终检合格数合计) + MAX(收检数量.不合格数合计) = MAX(v.计划数量) + OR MAX(v.计划数量) = MAX(v.入库数量) + OR MAX(收检数量.不合格数合计) = MAX(v.计划数量) + ) + AND MAX(ISNULL(v.入库数量, 0)) = MAX(ISNULL(终检数量.终检合格数合计, 0)) + + UNION ALL + + SELECT + CONVERT(nvarchar(100), p.订单编号) AS 订单编号, + MAX(p.物料描述) AS 产品名称, + MAX(p.物料编号) AS 产品编码, + MAX(p.入库数量) AS 入库数量, + MAX(p.合同号) AS 合同号, + MAX(终检数量.终检不合格数合计) AS 终检不合格数合计, + MAX(终检数量.终检合格数合计) AS 终检合格数合计, + MAX(p.计划数量) AS 计划数量, + MAX(p.确认状态) AS 确认状态, + MAX(p.单据状态) AS 单据状态, + MAX(收检数量.不合格数合计) AS 不合格数合计, + 1 AS 是否全部校验 + FROM dbo.MES_接口_生产计划 AS p + LEFT JOIN 收检数量 ON CONVERT(nvarchar(100), p.订单编号) = CONVERT(nvarchar(100), 收检数量.计划号) + LEFT JOIN 终检数量 ON CONVERT(nvarchar(100), p.订单编号) = CONVERT(nvarchar(100), 终检数量.计划号) + LEFT JOIN #工时订单 AS wh ON wh.订单号 = CONVERT(nvarchar(100), p.订单编号) + WHERE p.单据状态 IS NULL + AND wh.订单号 IS NULL + AND (@订单号 = N'' OR CONVERT(nvarchar(100), p.订单编号) = @订单号) + AND ( + @属性 NOT IN (N'机加', N'装配') + OR (@属性 = N'机加' AND p.自制件属性 = N'机加件') + OR (@属性 = N'装配' AND p.自制件属性 LIKE N'%装配%') + ) + GROUP BY p.订单编号 + HAVING + ( + MAX(终检数量.终检合格数合计) + MAX(收检数量.不合格数合计) = MAX(p.计划数量) + OR MAX(p.计划数量) = MAX(p.入库数量) + OR MAX(收检数量.不合格数合计) = MAX(p.计划数量) + ) + AND MAX(ISNULL(p.入库数量, 0)) = MAX(ISNULL(终检数量.终检合格数合计, 0)) + ) + SELECT + 订单编号, + 产品名称, + 产品编码, + 入库数量, + 合同号, + 终检不合格数合计, + 终检合格数合计, + 计划数量, + 确认状态, + 单据状态, + 不合格数合计, + 是否全部校验 + FROM 可关闭订单 + ORDER BY 订单编号; + + RETURN; + END + + SELECT TOP 100 + v.订单编号, + MAX(v.物料描述) AS 产品名称, + MAX(v.物料编号) AS 产品编码, + MAX(v.入库数量) AS 入库数量, + MAX(v.合同号) AS 合同号, + MAX(zj_终检数量.终检不合格数合计) AS 终检不合格数合计, + MAX(zj_终检数量.终检合格数合计) AS 终检合格数合计, + MAX(v.计划数量) AS 计划数量, + MAX(v.确认状态) AS 确认状态, + MAX(v.单据状态) AS 单据状态 + FROM dbo.MES_接口_生产计划 AS v + LEFT JOIN + ( + SELECT + 计划号, + SUM(ISNULL(合格数, 0)) AS 终检合格数合计, + SUM(ISNULL(不合格数, 0)) AS 终检不合格数合计 + FROM dbo.YL_质量检验_质检记录 + WHERE 质检类型 = N'终检' + GROUP BY 计划号 + ) AS zj_终检数量 ON v.订单编号 = zj_终检数量.计划号 + WHERE 1 = 1 + AND (@订单号 = N'' OR CONVERT(nvarchar(100), v.订单编号) = @订单号) + AND ( + @单据状态 NOT IN (N'SAP未关闭', N'已关闭', N'未关闭') + OR (@单据状态 = N'SAP未关闭' AND v.单据状态 = N'已关闭') + OR (@单据状态 = N'已关闭' AND (v.单据状态 = N'已关闭' OR v.单据状态 = N'已取消')) + OR (@单据状态 = N'未关闭' AND v.单据状态 IS NULL) + ) + AND ( + @属性 NOT IN (N'机加', N'装配') + OR (@属性 = N'机加' AND v.自制件属性 = N'机加件') + OR (@属性 = N'装配' AND v.自制件属性 LIKE N'%装配%') + ) + GROUP BY v.订单编号; +END +GO diff --git a/db_backups/update_timely_kit_tracking_result_inventory_20260630.sql b/db_backups/update_timely_kit_tracking_result_inventory_20260630.sql new file mode 100644 index 0000000..c0aa6d6 --- /dev/null +++ b/db_backups/update_timely_kit_tracking_result_inventory_20260630.sql @@ -0,0 +1,409 @@ +USE [YL_MESDB] +GO + +SET ANSI_NULLS ON +GO + +SET QUOTED_IDENTIFIER ON +GO + +IF OBJECT_ID(N'dbo.生产管理_及时齐套跟踪结果_查询', N'P') IS NULL +BEGIN + EXEC(N'CREATE PROCEDURE [dbo].[生产管理_及时齐套跟踪结果_查询] AS BEGIN SET NOCOUNT ON; END'); +END +GO + +SET ANSI_NULLS ON +GO + +SET QUOTED_IDENTIFIER ON +GO + +ALTER PROCEDURE [dbo].[生产管理_及时齐套跟踪结果_查询] + @订单号 int = 0, + @物料类型 nvarchar(50) = N'', + @合同号 nvarchar(50) = N'', + @产品编码 nvarchar(50) = N'', + @产品名称 nvarchar(50) = N'', + @工序名称 nvarchar(50) = N'', + @计划开始 nvarchar(50) = N'', + @计划完成 nvarchar(50) = N'', + @排产状态 nvarchar(50) = N'全部', + @指派对象 nvarchar(50) = N'全部', + @计划号 nvarchar(50) = N'', + @发货状态 nvarchar(50) = N'全部', + @齐套 nvarchar(50) = N'全部', + @检验状态 nvarchar(50) = N'', + @发料状态 nvarchar(50) = N'全部', + @自制件属性 nvarchar(50) = N'全部' +AS +BEGIN + SET NOCOUNT ON; + + ;WITH SAP缺件源 AS ( + SELECT + s.DocEntry, + s.Project COLLATE DATABASE_DEFAULT AS Project, + s.[行号], + s.ItemCode COLLATE DATABASE_DEFAULT AS ItemCode, + s.U_Name COLLATE DATABASE_DEFAULT AS U_Name, + ISNULL(s.[属性] COLLATE DATABASE_DEFAULT, N'') AS 属性, + ISNULL(s.[未发货数量], 0) AS 未发货数量, + ISNULL(s.[库存量], 0) AS 库存数量, + ISNULL(s.[在制采购], 0) AS 在制采购, + s.[采购预计交货日期], + ISNULL(s.[采购未清数量], 0) AS 采购未清数量, + ISNULL(s.[到货草稿], 0) AS 到货草稿 + FROM [SAP].[SBO_YL].[dbo].[VIEW_Jijiankukc] AS s + WHERE ISNULL(s.[未发货数量], 0) > 0 + ), + SAP缺件 AS ( + SELECT TOP (2000) + src.* + FROM ( + SELECT + SAP缺件源.*, + ROW_NUMBER() OVER ( + PARTITION BY + SAP缺件源.DocEntry, + SAP缺件源.Project, + SAP缺件源.ItemCode, + SAP缺件源.属性 + ORDER BY + SAP缺件源.[未发货数量] DESC, + SAP缺件源.[行号] + ) AS rn + FROM SAP缺件源 + ) AS src + WHERE src.rn = 1 + ), + 查询结果 AS ( + SELECT + ISNULL(v.[计划号], N'') AS [计划号], + ISNULL(v.[合同号], N'') AS [合同号], + v.[订单编号] AS [订单号], + v.[物料编号] AS [产品编码], + v.[物料描述] AS [产品名称], + v.[计划数量订单], + v.[入库数量], + v.[计划完成] AS [要求完工日期], + v.[要求发货日期], + CASE + WHEN ISNULL(v.[发货状态], 0) = 1 THEN N'已发货' + ELSE N'未发货' + END AS [发货状态], + CASE + WHEN ISNULL(v.[齐套], 0) = 1 THEN N'是' + ELSE N'否' + END AS [齐套], + CASE + WHEN ISNULL(v.[拣配状态], 0) = 1 THEN N'已拣配' + ELSE N'未拣配' + END AS [拣配状态], + CASE + WHEN ISNULL(v.[发料状态], N'') = N'1' THEN N'发料齐套' + WHEN ISNULL(v.[发料状态], N'') = N'2' THEN N'发料缺件' + ELSE N'未发料' + END AS [发料状态], + CASE + WHEN ISNULL(v.[任务状态], 0) IN (2, 4) OR v.[开工时间] > '1900-01-01' THEN N'已开工' + ELSE N'待执行' + END AS [装配开工], + v.[完成数量], + CASE + WHEN final_check.[计划号] IS NOT NULL THEN N'是' + ELSE N'否' + END AS [终检], + CASE WHEN ISNULL(v.[生产工艺], 0) = 1 THEN N'是' ELSE N'否' END AS [生产工艺], + CASE WHEN ISNULL(v.[排产状态], 0) = 1 THEN N'已排产' ELSE N'未排产' END AS [排产状态], + ISNULL(v.[自制件属性], N'') AS [自制件属性], + v.[计划开始时间] AS [预计齐套时间], + sap.ItemCode AS [缺件物料编码], + sap.U_Name AS [缺件物料名称], + sap.[未发货数量] AS [缺件数量], + sap.[库存数量] AS [库存数量], + CASE WHEN sap.[属性] = N'' THEN N'外购' ELSE sap.[属性] END AS [缺件属性], + CASE + WHEN sap.[属性] = N'' THEN ISNULL(CONVERT(nvarchar(50), NULLIF(sap.[到货草稿], 0)), N'') + ELSE ISNULL(CONVERT(nvarchar(50), detail_order.[订单编号]), N'') + END AS [缺件生产订单号], + CASE WHEN sap.[属性] = N'' THEN N'' ELSE ISNULL(current_step.[当前序], N'') END AS [进度], + CASE + WHEN sap.[属性] = N'' THEN + N'未清数量:' + CONVERT(nvarchar(30), sap.[采购未清数量]) + + N' / 到货草稿:' + CONVERT(nvarchar(30), sap.[到货草稿]) + + N' / 质检状态:' + ISNULL(purchase_check.[质检状态], N'未完成') + ELSE ISNULL(route.[工艺路线], N'') + END AS [工艺路线], + CASE + WHEN sap.[属性] = N'' THEN sap.[采购预计交货日期] + ELSE route.[预计完成时间] + END AS [预计完成时间], + CASE WHEN sap.[属性] = N'' THEN N'' ELSE ISNULL(route.[工艺路线明细], N'[]') END AS [工艺路线明细], + sap.[采购未清数量], + sap.[到货草稿], + ISNULL(purchase_check.[质检状态], CASE WHEN sap.[属性] = N'' THEN N'未完成' ELSE N'' END) AS [质检状态], + sap.DocEntry AS [SAP单据], + sap.[行号] AS [SAP行号] + FROM SAP缺件 AS sap + OUTER APPLY ( + SELECT TOP (1) m.* + FROM [dbo].[View_生产订单_MES] AS m + WHERE m.[物料类型] = N'pit_Resource' + AND ISNULL(m.[排产状态], 0) = 1 + AND m.[订单编号] = sap.DocEntry + ORDER BY m.[订单行号] + ) AS v + OUTER APPLY ( + SELECT TOP (1) m.* + FROM [dbo].[View_生产订单_MES] AS m + WHERE m.[物料类型] = N'pit_Resource' + AND ISNULL(m.[排产状态], 0) = 1 + AND m.[订单编号] <> v.[订单编号] + AND ( + (sap.[属性] = N'机加件' AND m.[物料编号] = sap.ItemCode) + OR (sap.[属性] LIKE N'%装配%' AND m.[物料编号] = sap.ItemCode AND ISNULL(m.[合同号], N'') = ISNULL(sap.Project, N'')) + ) + ORDER BY m.[订单编号] DESC, m.[订单行号] + ) AS detail_order + OUTER APPLY ( + SELECT TOP (1) q.[计划号] + FROM [dbo].[YL_质量检验_质检记录] AS q + WHERE q.[质检类型] = N'终检' + AND q.[计划号] = v.[订单编号] + ) AS final_check + OUTER APPLY ( + SELECT + MAX(p.[计划完成时间]) AS [预计完成时间], + STUFF(( + SELECT N'、' + p2.[工序名称] + + CASE WHEN ISNULL(p2.[指派对象], N'') = N'' THEN N'' ELSE N'(' + p2.[指派对象] + N')' END + FROM [dbo].[View_生产订单_MES] AS p2 + WHERE p2.[订单编号] = detail_order.[订单编号] + AND p2.[物料类型] = N'pit_Resource' + ORDER BY p2.[订单行号] + FOR XML PATH(N''), TYPE + ).value(N'.', N'nvarchar(max)'), 1, 1, N'') AS [工艺路线], + ( + SELECT + p2.[订单行号], + p2.[工序名称], + p2.[指派对象], + p2.[计划开始时间], + p2.[计划完成时间], + ISNULL(p2.[进度], 0) AS [进度], + ISNULL(p2.[完成数量], 0) AS [完成数量], + ISNULL(p2.[收料数量], 0) AS [收料数量], + ISNULL(p2.[加工状态], 0) AS [加工状态], + p2.[开工时间], + ISNULL(check_qty.[收检合格数], 0) AS [收检合格数], + ISNULL(check_qty.[收检不合格数], 0) AS [收检不合格数] + FROM [dbo].[View_生产订单_MES] AS p2 + OUTER APPLY ( + SELECT + SUM(ISNULL(q.[合格数], 0)) AS [收检合格数], + SUM(ISNULL(q.[不合格数], 0)) AS [收检不合格数] + FROM [dbo].[YL_质量检验_质检记录] AS q + WHERE q.[TaskAID] = p2.[TaskAID] + AND q.[质检类型] = N'收检' + ) AS check_qty + WHERE p2.[订单编号] = detail_order.[订单编号] + AND p2.[物料类型] = N'pit_Resource' + ORDER BY p2.[订单行号] + FOR JSON PATH + ) AS [工艺路线明细] + FROM [dbo].[View_生产订单_MES] AS p + WHERE p.[订单编号] = detail_order.[订单编号] + AND p.[物料类型] = N'pit_Resource' + ) AS route + OUTER APPLY ( + SELECT TOP (1) + pending.[订单行号], + pending.[工序名称], + pending.[加工状态], + pending.[进度], + pending.[完成数量], + pending.[计划数量], + pending.[开工时间] + FROM [dbo].[View_生产订单_MES] AS pending + WHERE pending.[订单编号] = detail_order.[订单编号] + AND pending.[物料类型] = N'pit_Resource' + AND NOT ( + ISNULL(pending.[进度], 0) >= 100 + OR (ISNULL(pending.[计划数量], 0) > 0 AND ISNULL(pending.[完成数量], 0) >= ISNULL(pending.[计划数量], 0)) + ) + ORDER BY pending.[订单行号] + ) AS pending + OUTER APPLY ( + SELECT TOP (1) prev.[工序名称] + FROM [dbo].[View_生产订单_MES] AS prev + WHERE prev.[订单编号] = detail_order.[订单编号] + AND prev.[物料类型] = N'pit_Resource' + AND prev.[订单行号] < pending.[订单行号] + ORDER BY prev.[订单行号] DESC + ) AS prev_step + OUTER APPLY ( + SELECT TOP (1) last_step.[工序名称] + FROM [dbo].[View_生产订单_MES] AS last_step + WHERE last_step.[订单编号] = detail_order.[订单编号] + AND last_step.[物料类型] = N'pit_Resource' + ORDER BY last_step.[订单行号] DESC + ) AS last_step + OUTER APPLY ( + SELECT + CASE + WHEN detail_order.[订单编号] IS NULL THEN N'' + WHEN pending.[订单行号] IS NULL THEN ISNULL(last_step.[工序名称], N'') + N'毕' + WHEN ISNULL(pending.[进度], 0) > 0 + OR ISNULL(pending.[完成数量], 0) > 0 + OR ISNULL(pending.[加工状态], 0) IN (2, 3, 4, 5, 6) + OR pending.[开工时间] > '1900-01-01' + THEN ISNULL(pending.[工序名称], N'') + N'中' + WHEN prev_step.[工序名称] IS NULL THEN N'' + ELSE prev_step.[工序名称] + N'毕待' + ISNULL(pending.[工序名称], N'') + END AS [当前序] + ) AS current_step + OUTER APPLY ( + SELECT + CASE + WHEN sap.[属性] <> N'' THEN N'' + WHEN EXISTS ( + SELECT 1 + FROM [dbo].[质量检验_质检任务_SAP] AS task + OUTER APPLY ( + SELECT SUM(ISNULL(q.[检验数量], 0)) AS [已检验数量] + FROM [dbo].[YL_质量检验_质检记录] AS q + WHERE q.[检测类型编号] = 5 + AND q.[计划号] = task.[订单编号] + AND q.[行号] = task.[行号] + AND q.[订单类型] = task.[订单类型] + ) AS checked_qty + WHERE sap.[到货草稿] > 0 + AND task.[订单类型] = N'20' + AND task.[订单编号] = sap.[到货草稿] + AND ISNULL(task.[入库数量], 0) > 0 + ) + AND NOT EXISTS ( + SELECT 1 + FROM [dbo].[质量检验_质检任务_SAP] AS task + OUTER APPLY ( + SELECT SUM(ISNULL(q.[检验数量], 0)) AS [已检验数量] + FROM [dbo].[YL_质量检验_质检记录] AS q + WHERE q.[检测类型编号] = 5 + AND q.[计划号] = task.[订单编号] + AND q.[行号] = task.[行号] + AND q.[订单类型] = task.[订单类型] + ) AS checked_qty + WHERE sap.[到货草稿] > 0 + AND task.[订单类型] = N'20' + AND task.[订单编号] = sap.[到货草稿] + AND ( + ISNULL(task.[入库数量], 0) <= 0 + OR ISNULL(checked_qty.[已检验数量], 0) < ISNULL(task.[入库数量], 0) + ) + ) THEN N'已完成' + ELSE N'未完成' + END AS [质检状态] + ) AS purchase_check + WHERE + v.[订单编号] IS NOT NULL + AND (@订单号 <= 0 OR v.[订单编号] = @订单号) + AND (@计划号 = N'' OR ISNULL(v.[计划号], N'') = @计划号) + AND (@合同号 = N'' OR ISNULL(v.[合同号], N'') LIKE N'%' + @合同号 + N'%') + AND (@产品编码 = N'' OR ISNULL(v.[物料编号], N'') LIKE N'%' + @产品编码 + N'%') + AND (@产品名称 = N'' OR ISNULL(v.[物料描述], N'') LIKE N'%' + @产品名称 + N'%') + AND (@工序名称 = N'' OR EXISTS ( + SELECT 1 + FROM [dbo].[View_生产订单_MES] AS fp + WHERE fp.[订单编号] = v.[订单编号] + AND fp.[工序名称] = @工序名称 + )) + AND (@计划开始 = N'' OR v.[计划开始时间] >= TRY_CONVERT(datetime, @计划开始)) + AND (@计划完成 = N'' OR v.[计划开始时间] <= TRY_CONVERT(datetime, @计划完成)) + AND (@排产状态 = N'全部' OR @排产状态 = N'' OR + (@排产状态 = N'已完成' AND ISNULL(v.[排产状态], 0) = 1) OR + (@排产状态 = N'未完成' AND ISNULL(v.[排产状态], 0) = 0) + ) + AND (@指派对象 = N'全部' OR @指派对象 = N'' OR EXISTS ( + SELECT 1 + FROM [dbo].[View_生产订单_MES] AS ap + WHERE ap.[订单编号] = v.[订单编号] + AND ap.[指派对象] IN (SELECT LTRIM(RTRIM(value)) FROM STRING_SPLIT(@指派对象, N',')) + )) + AND (@发货状态 = N'全部' OR @发货状态 = N'' OR + (@发货状态 = N'已发货' AND ISNULL(v.[发货状态], N'0') = N'1') OR + (@发货状态 = N'未发货' AND ISNULL(v.[发货状态], N'0') <> N'1') + ) + AND (@齐套 = N'全部' OR @齐套 = N'' OR + (@齐套 = N'是' AND ISNULL(v.[齐套], 0) = 1) OR + (@齐套 = N'否' AND ISNULL(v.[齐套], 0) <> 1) + ) + AND (@发料状态 = N'全部' OR @发料状态 = N'' OR + (@发料状态 = N'发料齐套' AND ISNULL(v.[发料状态], N'0') = N'1') OR + (@发料状态 = N'发料缺件' AND ISNULL(v.[发料状态], N'0') = N'2') OR + (@发料状态 = N'未发料' AND ISNULL(v.[发料状态], N'0') NOT IN (N'1', N'2')) + ) + AND (@自制件属性 = N'全部' OR @自制件属性 = N'' OR + (@自制件属性 = N'机加' AND (sap.[属性] = N'机加件' OR v.[自制件属性] = N'机加件')) OR + (@自制件属性 = N'装配' AND (sap.[属性] LIKE N'%装配%' OR v.[自制件属性] LIKE N'%装配%')) + ) + AND (@检验状态 = N'' OR (sap.[属性] = N'' AND ISNULL(purchase_check.[质检状态], N'') = @检验状态)) + ) + SELECT TOP (1000) + [计划号], + [合同号], + [订单号], + [产品编码], + [产品名称], + [计划数量订单], + [入库数量], + [要求完工日期], + [要求发货日期], + [发货状态], + [齐套], + [拣配状态], + [发料状态], + [装配开工], + [完成数量], + [终检], + [生产工艺], + [排产状态], + [自制件属性], + [预计齐套时间], + [缺件物料编码], + [缺件物料名称], + [缺件数量], + [库存数量], + [缺件属性], + [缺件生产订单号], + [进度], + [工艺路线], + [预计完成时间], + [工艺路线明细], + [采购未清数量], + [到货草稿], + [质检状态], + [SAP单据], + [SAP行号] + FROM ( + SELECT + 查询结果.*, + ROW_NUMBER() OVER ( + PARTITION BY + [订单号], + CASE + WHEN ISNULL([缺件生产订单号], N'') <> N'' THEN [缺件生产订单号] + ELSE [缺件物料编码] + N':' + CONVERT(nvarchar(30), [SAP行号]) + END + ORDER BY [缺件数量] DESC, [SAP单据], [SAP行号] + ) AS rn + FROM 查询结果 + ) AS dedup + WHERE rn = 1 + ORDER BY + [预计齐套时间], + [订单号], + [缺件生产订单号], + [缺件物料编码]; +END +GO diff --git a/db_backups/update_timely_kit_tracking_result_multi_detail_orders_20260630.sql b/db_backups/update_timely_kit_tracking_result_multi_detail_orders_20260630.sql new file mode 100644 index 0000000..5363c03 --- /dev/null +++ b/db_backups/update_timely_kit_tracking_result_multi_detail_orders_20260630.sql @@ -0,0 +1,423 @@ +USE [YL_MESDB] +GO + +SET ANSI_NULLS ON +GO + +SET QUOTED_IDENTIFIER ON +GO + +IF OBJECT_ID(N'dbo.生产管理_及时齐套跟踪结果_查询', N'P') IS NULL +BEGIN + EXEC(N'CREATE PROCEDURE [dbo].[生产管理_及时齐套跟踪结果_查询] AS BEGIN SET NOCOUNT ON; END'); +END +GO + +SET ANSI_NULLS ON +GO + +SET QUOTED_IDENTIFIER ON +GO + +ALTER PROCEDURE [dbo].[生产管理_及时齐套跟踪结果_查询] + @订单号 int = 0, + @物料类型 nvarchar(50) = N'', + @合同号 nvarchar(50) = N'', + @产品编码 nvarchar(50) = N'', + @产品名称 nvarchar(50) = N'', + @工序名称 nvarchar(50) = N'', + @计划开始 nvarchar(50) = N'', + @计划完成 nvarchar(50) = N'', + @排产状态 nvarchar(50) = N'全部', + @指派对象 nvarchar(50) = N'全部', + @计划号 nvarchar(50) = N'', + @发货状态 nvarchar(50) = N'全部', + @齐套 nvarchar(50) = N'全部', + @检验状态 nvarchar(50) = N'', + @发料状态 nvarchar(50) = N'全部', + @自制件属性 nvarchar(50) = N'全部' +AS +BEGIN + SET NOCOUNT ON; + + ;WITH SAP缺件源 AS ( + SELECT + s.DocEntry, + s.Project COLLATE DATABASE_DEFAULT AS Project, + s.[行号], + s.ItemCode COLLATE DATABASE_DEFAULT AS ItemCode, + s.U_Name COLLATE DATABASE_DEFAULT AS U_Name, + ISNULL(s.[属性] COLLATE DATABASE_DEFAULT, N'') AS 属性, + ISNULL(s.[未发货数量], 0) AS 未发货数量, + ISNULL(s.[库存量], 0) AS 库存数量, + ISNULL(s.[在制采购], 0) AS 在制采购, + ISNULL(s.DocNum, 0) AS DocNum, + s.[采购员] COLLATE DATABASE_DEFAULT AS 采购员, + s.[采购预计交货日期], + ISNULL(s.[采购未清数量], 0) AS 采购未清数量, + ISNULL(s.[到货草稿], 0) AS 到货草稿 + FROM [SAP].[SBO_YL].[dbo].[VIEW_Jijiankukc] AS s + WHERE ISNULL(s.[未发货数量], 0) > 0 + ), + SAP缺件 AS ( + SELECT TOP (2000) + src.* + FROM ( + SELECT + SAP缺件源.*, + ROW_NUMBER() OVER ( + PARTITION BY + SAP缺件源.DocEntry, + SAP缺件源.Project, + SAP缺件源.ItemCode, + SAP缺件源.属性 + ORDER BY + SAP缺件源.[未发货数量] DESC, + SAP缺件源.[行号] + ) AS rn + FROM SAP缺件源 + ) AS src + WHERE src.rn = 1 + ), + 查询结果 AS ( + SELECT + ISNULL(v.[计划号], N'') AS [计划号], + ISNULL(v.[合同号], N'') AS [合同号], + v.[订单编号] AS [订单号], + v.[物料编号] AS [产品编码], + v.[物料描述] AS [产品名称], + v.[计划数量订单], + v.[入库数量], + v.[计划完成] AS [要求完工日期], + v.[要求发货日期], + CASE + WHEN ISNULL(v.[发货状态], 0) = 1 THEN N'已发货' + ELSE N'未发货' + END AS [发货状态], + CASE + WHEN ISNULL(v.[齐套], 0) = 1 THEN N'是' + ELSE N'否' + END AS [齐套], + CASE + WHEN ISNULL(v.[拣配状态], 0) = 1 THEN N'已拣配' + ELSE N'未拣配' + END AS [拣配状态], + CASE + WHEN ISNULL(v.[发料状态], N'') = N'1' THEN N'发料齐套' + WHEN ISNULL(v.[发料状态], N'') = N'2' THEN N'发料缺件' + ELSE N'未发料' + END AS [发料状态], + CASE + WHEN ISNULL(v.[任务状态], 0) IN (2, 4) OR v.[开工时间] > '1900-01-01' THEN N'已开工' + ELSE N'待执行' + END AS [装配开工], + v.[完成数量], + CASE + WHEN final_check.[计划号] IS NOT NULL THEN N'是' + ELSE N'否' + END AS [终检], + CASE WHEN ISNULL(v.[生产工艺], 0) = 1 THEN N'是' ELSE N'否' END AS [生产工艺], + CASE WHEN ISNULL(v.[排产状态], 0) = 1 THEN N'已排产' ELSE N'未排产' END AS [排产状态], + ISNULL(v.[自制件属性], N'') AS [自制件属性], + v.[计划开始时间] AS [预计齐套时间], + sap.ItemCode AS [缺件物料编码], + sap.U_Name AS [缺件物料名称], + sap.[未发货数量] AS [缺件数量], + sap.[库存数量] AS [库存数量], + CASE WHEN sap.[属性] = N'' THEN N'外购' ELSE sap.[属性] END AS [缺件属性], + CASE + WHEN sap.[属性] = N'' THEN ISNULL(CONVERT(nvarchar(50), NULLIF(sap.[在制采购], 0)), N'') + ELSE ISNULL(CONVERT(nvarchar(50), detail_order.[订单编号]), N'') + END AS [缺件生产订单号], + CASE WHEN sap.[属性] = N'' THEN N'' ELSE ISNULL(current_step.[当前序], N'') END AS [进度], + CASE + WHEN sap.[属性] = N'' THEN + N'采购员:' + ISNULL(NULLIF(sap.[采购员], N''), N'-') + + N' / 未清数量:' + CONVERT(nvarchar(30), sap.[采购未清数量]) + + N' / 到货草稿:' + CONVERT(nvarchar(30), sap.[到货草稿]) + + N' / 质检状态:' + ISNULL(purchase_check.[质检状态], N'未完成') + ELSE ISNULL(route.[工艺路线], N'') + END AS [工艺路线], + CASE + WHEN sap.[属性] = N'' THEN sap.[采购预计交货日期] + ELSE route.[预计完成时间] + END AS [预计完成时间], + CASE WHEN sap.[属性] = N'' THEN N'' ELSE ISNULL(route.[工艺路线明细], N'[]') END AS [工艺路线明细], + sap.[采购未清数量], + sap.[到货草稿], + ISNULL(purchase_check.[质检状态], CASE WHEN sap.[属性] = N'' THEN N'未完成' ELSE N'' END) AS [质检状态], + sap.DocEntry AS [SAP单据], + sap.[行号] AS [SAP行号] + FROM SAP缺件 AS sap + OUTER APPLY ( + SELECT TOP (1) m.* + FROM [dbo].[View_生产订单_MES] AS m + WHERE m.[物料类型] = N'pit_Resource' + AND ISNULL(m.[排产状态], 0) = 1 + AND m.[订单编号] = sap.DocEntry + ORDER BY m.[订单行号] + ) AS v + OUTER APPLY ( + SELECT m.* + FROM ( + SELECT + m.*, + ROW_NUMBER() OVER ( + PARTITION BY m.[订单编号] + ORDER BY m.[订单行号] + ) AS rn + FROM [dbo].[View_生产订单_MES] AS m + WHERE m.[物料类型] = N'pit_Resource' + AND ISNULL(m.[排产状态], 0) = 1 + AND m.[订单编号] <> v.[订单编号] + AND ( + (sap.[属性] = N'机加件' AND ( + m.[物料编号] = sap.ItemCode + OR (sap.DocNum > 0 AND m.[订单编号] = sap.DocNum) + )) + OR (sap.[属性] LIKE N'%装配%' AND m.[物料编号] = sap.ItemCode AND ISNULL(m.[合同号], N'') = ISNULL(sap.Project, N'')) + ) + ) AS m + WHERE m.rn = 1 + ) AS detail_order + OUTER APPLY ( + SELECT TOP (1) q.[计划号] + FROM [dbo].[YL_质量检验_质检记录] AS q + WHERE q.[质检类型] = N'终检' + AND q.[计划号] = v.[订单编号] + ) AS final_check + OUTER APPLY ( + SELECT + MAX(p.[计划完成时间]) AS [预计完成时间], + STUFF(( + SELECT N'、' + p2.[工序名称] + + CASE WHEN ISNULL(p2.[指派对象], N'') = N'' THEN N'' ELSE N'(' + p2.[指派对象] + N')' END + FROM [dbo].[View_生产订单_MES] AS p2 + WHERE p2.[订单编号] = detail_order.[订单编号] + AND p2.[物料类型] = N'pit_Resource' + ORDER BY p2.[订单行号] + FOR XML PATH(N''), TYPE + ).value(N'.', N'nvarchar(max)'), 1, 1, N'') AS [工艺路线], + ( + SELECT + p2.[订单行号], + p2.[工序名称], + p2.[指派对象], + p2.[计划开始时间], + p2.[计划完成时间], + ISNULL(p2.[进度], 0) AS [进度], + ISNULL(p2.[完成数量], 0) AS [完成数量], + ISNULL(p2.[收料数量], 0) AS [收料数量], + ISNULL(p2.[加工状态], 0) AS [加工状态], + p2.[开工时间], + ISNULL(check_qty.[收检合格数], 0) AS [收检合格数], + ISNULL(check_qty.[收检不合格数], 0) AS [收检不合格数] + FROM [dbo].[View_生产订单_MES] AS p2 + OUTER APPLY ( + SELECT + SUM(ISNULL(q.[合格数], 0)) AS [收检合格数], + SUM(ISNULL(q.[不合格数], 0)) AS [收检不合格数] + FROM [dbo].[YL_质量检验_质检记录] AS q + WHERE q.[TaskAID] = p2.[TaskAID] + AND q.[质检类型] = N'收检' + ) AS check_qty + WHERE p2.[订单编号] = detail_order.[订单编号] + AND p2.[物料类型] = N'pit_Resource' + ORDER BY p2.[订单行号] + FOR JSON PATH + ) AS [工艺路线明细] + FROM [dbo].[View_生产订单_MES] AS p + WHERE p.[订单编号] = detail_order.[订单编号] + AND p.[物料类型] = N'pit_Resource' + ) AS route + OUTER APPLY ( + SELECT TOP (1) + pending.[订单行号], + pending.[工序名称], + pending.[加工状态], + pending.[进度], + pending.[完成数量], + pending.[计划数量], + pending.[开工时间] + FROM [dbo].[View_生产订单_MES] AS pending + WHERE pending.[订单编号] = detail_order.[订单编号] + AND pending.[物料类型] = N'pit_Resource' + AND NOT ( + ISNULL(pending.[进度], 0) >= 100 + OR (ISNULL(pending.[计划数量], 0) > 0 AND ISNULL(pending.[完成数量], 0) >= ISNULL(pending.[计划数量], 0)) + ) + ORDER BY pending.[订单行号] + ) AS pending + OUTER APPLY ( + SELECT TOP (1) prev.[工序名称] + FROM [dbo].[View_生产订单_MES] AS prev + WHERE prev.[订单编号] = detail_order.[订单编号] + AND prev.[物料类型] = N'pit_Resource' + AND prev.[订单行号] < pending.[订单行号] + ORDER BY prev.[订单行号] DESC + ) AS prev_step + OUTER APPLY ( + SELECT TOP (1) last_step.[工序名称] + FROM [dbo].[View_生产订单_MES] AS last_step + WHERE last_step.[订单编号] = detail_order.[订单编号] + AND last_step.[物料类型] = N'pit_Resource' + ORDER BY last_step.[订单行号] DESC + ) AS last_step + OUTER APPLY ( + SELECT + CASE + WHEN detail_order.[订单编号] IS NULL THEN N'' + WHEN pending.[订单行号] IS NULL THEN ISNULL(last_step.[工序名称], N'') + N'毕' + WHEN ISNULL(pending.[进度], 0) > 0 + OR ISNULL(pending.[完成数量], 0) > 0 + OR ISNULL(pending.[加工状态], 0) IN (2, 3, 4, 5, 6) + OR pending.[开工时间] > '1900-01-01' + THEN ISNULL(pending.[工序名称], N'') + N'中' + WHEN prev_step.[工序名称] IS NULL THEN N'' + ELSE prev_step.[工序名称] + N'毕待' + ISNULL(pending.[工序名称], N'') + END AS [当前序] + ) AS current_step + OUTER APPLY ( + SELECT + CASE + WHEN sap.[属性] <> N'' THEN N'' + WHEN EXISTS ( + SELECT 1 + FROM [dbo].[质量检验_质检任务_SAP] AS task + OUTER APPLY ( + SELECT SUM(ISNULL(q.[检验数量], 0)) AS [已检验数量] + FROM [dbo].[YL_质量检验_质检记录] AS q + WHERE q.[检测类型编号] = 5 + AND q.[计划号] = task.[订单编号] + AND q.[行号] = task.[行号] + AND q.[订单类型] = task.[订单类型] + ) AS checked_qty + WHERE sap.[到货草稿] > 0 + AND task.[订单类型] = N'20' + AND task.[订单编号] = sap.[到货草稿] + AND ISNULL(task.[入库数量], 0) > 0 + ) + AND NOT EXISTS ( + SELECT 1 + FROM [dbo].[质量检验_质检任务_SAP] AS task + OUTER APPLY ( + SELECT SUM(ISNULL(q.[检验数量], 0)) AS [已检验数量] + FROM [dbo].[YL_质量检验_质检记录] AS q + WHERE q.[检测类型编号] = 5 + AND q.[计划号] = task.[订单编号] + AND q.[行号] = task.[行号] + AND q.[订单类型] = task.[订单类型] + ) AS checked_qty + WHERE sap.[到货草稿] > 0 + AND task.[订单类型] = N'20' + AND task.[订单编号] = sap.[到货草稿] + AND ( + ISNULL(task.[入库数量], 0) <= 0 + OR ISNULL(checked_qty.[已检验数量], 0) < ISNULL(task.[入库数量], 0) + ) + ) THEN N'已完成' + ELSE N'未完成' + END AS [质检状态] + ) AS purchase_check + WHERE + v.[订单编号] IS NOT NULL + AND (@订单号 <= 0 OR v.[订单编号] = @订单号) + AND (@计划号 = N'' OR ISNULL(v.[计划号], N'') = @计划号) + AND (@合同号 = N'' OR ISNULL(v.[合同号], N'') LIKE N'%' + @合同号 + N'%') + AND (@产品编码 = N'' OR ISNULL(v.[物料编号], N'') LIKE N'%' + @产品编码 + N'%') + AND (@产品名称 = N'' OR ISNULL(v.[物料描述], N'') LIKE N'%' + @产品名称 + N'%') + AND (@工序名称 = N'' OR EXISTS ( + SELECT 1 + FROM [dbo].[View_生产订单_MES] AS fp + WHERE fp.[订单编号] = v.[订单编号] + AND fp.[工序名称] = @工序名称 + )) + AND (@计划开始 = N'' OR v.[计划开始时间] >= TRY_CONVERT(datetime, @计划开始)) + AND (@计划完成 = N'' OR v.[计划开始时间] <= TRY_CONVERT(datetime, @计划完成)) + AND (@排产状态 = N'全部' OR @排产状态 = N'' OR + (@排产状态 = N'已完成' AND ISNULL(v.[排产状态], 0) = 1) OR + (@排产状态 = N'未完成' AND ISNULL(v.[排产状态], 0) = 0) + ) + AND (@指派对象 = N'全部' OR @指派对象 = N'' OR EXISTS ( + SELECT 1 + FROM [dbo].[View_生产订单_MES] AS ap + WHERE ap.[订单编号] = v.[订单编号] + AND ap.[指派对象] IN (SELECT LTRIM(RTRIM(value)) FROM STRING_SPLIT(@指派对象, N',')) + )) + AND (@发货状态 = N'全部' OR @发货状态 = N'' OR + (@发货状态 = N'已发货' AND ISNULL(v.[发货状态], N'0') = N'1') OR + (@发货状态 = N'未发货' AND ISNULL(v.[发货状态], N'0') <> N'1') + ) + AND (@齐套 = N'全部' OR @齐套 = N'' OR + (@齐套 = N'是' AND ISNULL(v.[齐套], 0) = 1) OR + (@齐套 = N'否' AND ISNULL(v.[齐套], 0) <> 1) + ) + AND (@发料状态 = N'全部' OR @发料状态 = N'' OR + (@发料状态 = N'发料齐套' AND ISNULL(v.[发料状态], N'0') = N'1') OR + (@发料状态 = N'发料缺件' AND ISNULL(v.[发料状态], N'0') = N'2') OR + (@发料状态 = N'未发料' AND ISNULL(v.[发料状态], N'0') NOT IN (N'1', N'2')) + ) + AND (@自制件属性 = N'全部' OR @自制件属性 = N'' OR + (@自制件属性 = N'机加' AND (sap.[属性] = N'机加件' OR v.[自制件属性] = N'机加件')) OR + (@自制件属性 = N'装配' AND (sap.[属性] LIKE N'%装配%' OR v.[自制件属性] LIKE N'%装配%')) + ) + AND (@检验状态 = N'' OR (sap.[属性] = N'' AND ISNULL(purchase_check.[质检状态], N'') = @检验状态)) + ) + SELECT TOP (1000) + [计划号], + [合同号], + [订单号], + [产品编码], + [产品名称], + [计划数量订单], + [入库数量], + [要求完工日期], + [要求发货日期], + [发货状态], + [齐套], + [拣配状态], + [发料状态], + [装配开工], + [完成数量], + [终检], + [生产工艺], + [排产状态], + [自制件属性], + [预计齐套时间], + [缺件物料编码], + [缺件物料名称], + [缺件数量], + [库存数量], + [缺件属性], + [缺件生产订单号], + [进度], + [工艺路线], + [预计完成时间], + [工艺路线明细], + [采购未清数量], + [到货草稿], + [质检状态], + [SAP单据], + [SAP行号] + FROM ( + SELECT + 查询结果.*, + ROW_NUMBER() OVER ( + PARTITION BY + [订单号], + CASE + WHEN ISNULL([缺件生产订单号], N'') <> N'' THEN [缺件生产订单号] + ELSE [缺件物料编码] + N':' + CONVERT(nvarchar(30), [SAP行号]) + END + ORDER BY [缺件数量] DESC, [SAP单据], [SAP行号] + ) AS rn + FROM 查询结果 + ) AS dedup + WHERE rn = 1 + ORDER BY + [预计齐套时间], + [订单号], + [缺件生产订单号], + [缺件物料编码]; +END +GO diff --git a/db_backups/update_timely_kit_tracking_result_purchase_order_20260630.sql b/db_backups/update_timely_kit_tracking_result_purchase_order_20260630.sql new file mode 100644 index 0000000..6dd18bc --- /dev/null +++ b/db_backups/update_timely_kit_tracking_result_purchase_order_20260630.sql @@ -0,0 +1,418 @@ +USE [YL_MESDB] +GO + +SET ANSI_NULLS ON +GO + +SET QUOTED_IDENTIFIER ON +GO + +IF OBJECT_ID(N'dbo.生产管理_及时齐套跟踪结果_查询', N'P') IS NULL +BEGIN + EXEC(N'CREATE PROCEDURE [dbo].[生产管理_及时齐套跟踪结果_查询] AS BEGIN SET NOCOUNT ON; END'); +END +GO + +SET ANSI_NULLS ON +GO + +SET QUOTED_IDENTIFIER ON +GO + +ALTER PROCEDURE [dbo].[生产管理_及时齐套跟踪结果_查询] + @订单号 int = 0, + @物料类型 nvarchar(50) = N'', + @合同号 nvarchar(50) = N'', + @产品编码 nvarchar(50) = N'', + @产品名称 nvarchar(50) = N'', + @工序名称 nvarchar(50) = N'', + @计划开始 nvarchar(50) = N'', + @计划完成 nvarchar(50) = N'', + @排产状态 nvarchar(50) = N'全部', + @指派对象 nvarchar(50) = N'全部', + @计划号 nvarchar(50) = N'', + @发货状态 nvarchar(50) = N'全部', + @齐套 nvarchar(50) = N'全部', + @检验状态 nvarchar(50) = N'', + @发料状态 nvarchar(50) = N'全部', + @自制件属性 nvarchar(50) = N'全部' +AS +BEGIN + SET NOCOUNT ON; + + ;WITH SAP缺件源 AS ( + SELECT + s.DocEntry, + s.Project COLLATE DATABASE_DEFAULT AS Project, + s.[行号], + s.ItemCode COLLATE DATABASE_DEFAULT AS ItemCode, + s.U_Name COLLATE DATABASE_DEFAULT AS U_Name, + ISNULL(s.[属性] COLLATE DATABASE_DEFAULT, N'') AS 属性, + ISNULL(s.[未发货数量], 0) AS 未发货数量, + ISNULL(s.[库存量], 0) AS 库存数量, + ISNULL(s.[在制采购], 0) AS 在制采购, + ISNULL(s.DocNum, 0) AS DocNum, + s.[采购员] COLLATE DATABASE_DEFAULT AS 采购员, + s.[采购预计交货日期], + ISNULL(s.[采购未清数量], 0) AS 采购未清数量, + ISNULL(s.[到货草稿], 0) AS 到货草稿 + FROM [SAP].[SBO_YL].[dbo].[VIEW_Jijiankukc] AS s + WHERE ISNULL(s.[未发货数量], 0) > 0 + ), + SAP缺件 AS ( + SELECT TOP (2000) + src.* + FROM ( + SELECT + SAP缺件源.*, + ROW_NUMBER() OVER ( + PARTITION BY + SAP缺件源.DocEntry, + SAP缺件源.Project, + SAP缺件源.ItemCode, + SAP缺件源.属性 + ORDER BY + SAP缺件源.[未发货数量] DESC, + SAP缺件源.[行号] + ) AS rn + FROM SAP缺件源 + ) AS src + WHERE src.rn = 1 + ), + 查询结果 AS ( + SELECT + ISNULL(v.[计划号], N'') AS [计划号], + ISNULL(v.[合同号], N'') AS [合同号], + v.[订单编号] AS [订单号], + v.[物料编号] AS [产品编码], + v.[物料描述] AS [产品名称], + v.[计划数量订单], + v.[入库数量], + v.[计划完成] AS [要求完工日期], + v.[要求发货日期], + CASE + WHEN ISNULL(v.[发货状态], 0) = 1 THEN N'已发货' + ELSE N'未发货' + END AS [发货状态], + CASE + WHEN ISNULL(v.[齐套], 0) = 1 THEN N'是' + ELSE N'否' + END AS [齐套], + CASE + WHEN ISNULL(v.[拣配状态], 0) = 1 THEN N'已拣配' + ELSE N'未拣配' + END AS [拣配状态], + CASE + WHEN ISNULL(v.[发料状态], N'') = N'1' THEN N'发料齐套' + WHEN ISNULL(v.[发料状态], N'') = N'2' THEN N'发料缺件' + ELSE N'未发料' + END AS [发料状态], + CASE + WHEN ISNULL(v.[任务状态], 0) IN (2, 4) OR v.[开工时间] > '1900-01-01' THEN N'已开工' + ELSE N'待执行' + END AS [装配开工], + v.[完成数量], + CASE + WHEN final_check.[计划号] IS NOT NULL THEN N'是' + ELSE N'否' + END AS [终检], + CASE WHEN ISNULL(v.[生产工艺], 0) = 1 THEN N'是' ELSE N'否' END AS [生产工艺], + CASE WHEN ISNULL(v.[排产状态], 0) = 1 THEN N'已排产' ELSE N'未排产' END AS [排产状态], + ISNULL(v.[自制件属性], N'') AS [自制件属性], + v.[计划开始时间] AS [预计齐套时间], + sap.ItemCode AS [缺件物料编码], + sap.U_Name AS [缺件物料名称], + sap.[未发货数量] AS [缺件数量], + sap.[库存数量] AS [库存数量], + CASE WHEN sap.[属性] = N'' THEN N'外购' ELSE sap.[属性] END AS [缺件属性], + CASE + WHEN sap.[属性] = N'' THEN ISNULL(CONVERT(nvarchar(50), NULLIF(sap.[在制采购], 0)), N'') + ELSE ISNULL(CONVERT(nvarchar(50), detail_order.[订单编号]), N'') + END AS [缺件生产订单号], + CASE WHEN sap.[属性] = N'' THEN N'' ELSE ISNULL(current_step.[当前序], N'') END AS [进度], + CASE + WHEN sap.[属性] = N'' THEN + N'采购员:' + ISNULL(NULLIF(sap.[采购员], N''), N'-') + + N' / 未清数量:' + CONVERT(nvarchar(30), sap.[采购未清数量]) + + N' / 到货草稿:' + CONVERT(nvarchar(30), sap.[到货草稿]) + + N' / 质检状态:' + ISNULL(purchase_check.[质检状态], N'未完成') + ELSE ISNULL(route.[工艺路线], N'') + END AS [工艺路线], + CASE + WHEN sap.[属性] = N'' THEN sap.[采购预计交货日期] + ELSE route.[预计完成时间] + END AS [预计完成时间], + CASE WHEN sap.[属性] = N'' THEN N'' ELSE ISNULL(route.[工艺路线明细], N'[]') END AS [工艺路线明细], + sap.[采购未清数量], + sap.[到货草稿], + ISNULL(purchase_check.[质检状态], CASE WHEN sap.[属性] = N'' THEN N'未完成' ELSE N'' END) AS [质检状态], + sap.DocEntry AS [SAP单据], + sap.[行号] AS [SAP行号] + FROM SAP缺件 AS sap + OUTER APPLY ( + SELECT TOP (1) m.* + FROM [dbo].[View_生产订单_MES] AS m + WHERE m.[物料类型] = N'pit_Resource' + AND ISNULL(m.[排产状态], 0) = 1 + AND m.[订单编号] = sap.DocEntry + ORDER BY m.[订单行号] + ) AS v + OUTER APPLY ( + SELECT TOP (1) m.* + FROM [dbo].[View_生产订单_MES] AS m + WHERE m.[物料类型] = N'pit_Resource' + AND ISNULL(m.[排产状态], 0) = 1 + AND m.[订单编号] <> v.[订单编号] + AND ( + (sap.[属性] = N'机加件' AND ( + (sap.DocNum > 0 AND m.[订单编号] = sap.DocNum) + OR (sap.DocNum <= 0 AND m.[物料编号] = sap.ItemCode) + )) + OR (sap.[属性] LIKE N'%装配%' AND m.[物料编号] = sap.ItemCode AND ISNULL(m.[合同号], N'') = ISNULL(sap.Project, N'')) + ) + ORDER BY + CASE WHEN sap.DocNum > 0 AND m.[订单编号] = sap.DocNum THEN 0 ELSE 1 END, + m.[订单编号] DESC, + m.[订单行号] + ) AS detail_order + OUTER APPLY ( + SELECT TOP (1) q.[计划号] + FROM [dbo].[YL_质量检验_质检记录] AS q + WHERE q.[质检类型] = N'终检' + AND q.[计划号] = v.[订单编号] + ) AS final_check + OUTER APPLY ( + SELECT + MAX(p.[计划完成时间]) AS [预计完成时间], + STUFF(( + SELECT N'、' + p2.[工序名称] + + CASE WHEN ISNULL(p2.[指派对象], N'') = N'' THEN N'' ELSE N'(' + p2.[指派对象] + N')' END + FROM [dbo].[View_生产订单_MES] AS p2 + WHERE p2.[订单编号] = detail_order.[订单编号] + AND p2.[物料类型] = N'pit_Resource' + ORDER BY p2.[订单行号] + FOR XML PATH(N''), TYPE + ).value(N'.', N'nvarchar(max)'), 1, 1, N'') AS [工艺路线], + ( + SELECT + p2.[订单行号], + p2.[工序名称], + p2.[指派对象], + p2.[计划开始时间], + p2.[计划完成时间], + ISNULL(p2.[进度], 0) AS [进度], + ISNULL(p2.[完成数量], 0) AS [完成数量], + ISNULL(p2.[收料数量], 0) AS [收料数量], + ISNULL(p2.[加工状态], 0) AS [加工状态], + p2.[开工时间], + ISNULL(check_qty.[收检合格数], 0) AS [收检合格数], + ISNULL(check_qty.[收检不合格数], 0) AS [收检不合格数] + FROM [dbo].[View_生产订单_MES] AS p2 + OUTER APPLY ( + SELECT + SUM(ISNULL(q.[合格数], 0)) AS [收检合格数], + SUM(ISNULL(q.[不合格数], 0)) AS [收检不合格数] + FROM [dbo].[YL_质量检验_质检记录] AS q + WHERE q.[TaskAID] = p2.[TaskAID] + AND q.[质检类型] = N'收检' + ) AS check_qty + WHERE p2.[订单编号] = detail_order.[订单编号] + AND p2.[物料类型] = N'pit_Resource' + ORDER BY p2.[订单行号] + FOR JSON PATH + ) AS [工艺路线明细] + FROM [dbo].[View_生产订单_MES] AS p + WHERE p.[订单编号] = detail_order.[订单编号] + AND p.[物料类型] = N'pit_Resource' + ) AS route + OUTER APPLY ( + SELECT TOP (1) + pending.[订单行号], + pending.[工序名称], + pending.[加工状态], + pending.[进度], + pending.[完成数量], + pending.[计划数量], + pending.[开工时间] + FROM [dbo].[View_生产订单_MES] AS pending + WHERE pending.[订单编号] = detail_order.[订单编号] + AND pending.[物料类型] = N'pit_Resource' + AND NOT ( + ISNULL(pending.[进度], 0) >= 100 + OR (ISNULL(pending.[计划数量], 0) > 0 AND ISNULL(pending.[完成数量], 0) >= ISNULL(pending.[计划数量], 0)) + ) + ORDER BY pending.[订单行号] + ) AS pending + OUTER APPLY ( + SELECT TOP (1) prev.[工序名称] + FROM [dbo].[View_生产订单_MES] AS prev + WHERE prev.[订单编号] = detail_order.[订单编号] + AND prev.[物料类型] = N'pit_Resource' + AND prev.[订单行号] < pending.[订单行号] + ORDER BY prev.[订单行号] DESC + ) AS prev_step + OUTER APPLY ( + SELECT TOP (1) last_step.[工序名称] + FROM [dbo].[View_生产订单_MES] AS last_step + WHERE last_step.[订单编号] = detail_order.[订单编号] + AND last_step.[物料类型] = N'pit_Resource' + ORDER BY last_step.[订单行号] DESC + ) AS last_step + OUTER APPLY ( + SELECT + CASE + WHEN detail_order.[订单编号] IS NULL THEN N'' + WHEN pending.[订单行号] IS NULL THEN ISNULL(last_step.[工序名称], N'') + N'毕' + WHEN ISNULL(pending.[进度], 0) > 0 + OR ISNULL(pending.[完成数量], 0) > 0 + OR ISNULL(pending.[加工状态], 0) IN (2, 3, 4, 5, 6) + OR pending.[开工时间] > '1900-01-01' + THEN ISNULL(pending.[工序名称], N'') + N'中' + WHEN prev_step.[工序名称] IS NULL THEN N'' + ELSE prev_step.[工序名称] + N'毕待' + ISNULL(pending.[工序名称], N'') + END AS [当前序] + ) AS current_step + OUTER APPLY ( + SELECT + CASE + WHEN sap.[属性] <> N'' THEN N'' + WHEN EXISTS ( + SELECT 1 + FROM [dbo].[质量检验_质检任务_SAP] AS task + OUTER APPLY ( + SELECT SUM(ISNULL(q.[检验数量], 0)) AS [已检验数量] + FROM [dbo].[YL_质量检验_质检记录] AS q + WHERE q.[检测类型编号] = 5 + AND q.[计划号] = task.[订单编号] + AND q.[行号] = task.[行号] + AND q.[订单类型] = task.[订单类型] + ) AS checked_qty + WHERE sap.[到货草稿] > 0 + AND task.[订单类型] = N'20' + AND task.[订单编号] = sap.[到货草稿] + AND ISNULL(task.[入库数量], 0) > 0 + ) + AND NOT EXISTS ( + SELECT 1 + FROM [dbo].[质量检验_质检任务_SAP] AS task + OUTER APPLY ( + SELECT SUM(ISNULL(q.[检验数量], 0)) AS [已检验数量] + FROM [dbo].[YL_质量检验_质检记录] AS q + WHERE q.[检测类型编号] = 5 + AND q.[计划号] = task.[订单编号] + AND q.[行号] = task.[行号] + AND q.[订单类型] = task.[订单类型] + ) AS checked_qty + WHERE sap.[到货草稿] > 0 + AND task.[订单类型] = N'20' + AND task.[订单编号] = sap.[到货草稿] + AND ( + ISNULL(task.[入库数量], 0) <= 0 + OR ISNULL(checked_qty.[已检验数量], 0) < ISNULL(task.[入库数量], 0) + ) + ) THEN N'已完成' + ELSE N'未完成' + END AS [质检状态] + ) AS purchase_check + WHERE + v.[订单编号] IS NOT NULL + AND (@订单号 <= 0 OR v.[订单编号] = @订单号) + AND (@计划号 = N'' OR ISNULL(v.[计划号], N'') = @计划号) + AND (@合同号 = N'' OR ISNULL(v.[合同号], N'') LIKE N'%' + @合同号 + N'%') + AND (@产品编码 = N'' OR ISNULL(v.[物料编号], N'') LIKE N'%' + @产品编码 + N'%') + AND (@产品名称 = N'' OR ISNULL(v.[物料描述], N'') LIKE N'%' + @产品名称 + N'%') + AND (@工序名称 = N'' OR EXISTS ( + SELECT 1 + FROM [dbo].[View_生产订单_MES] AS fp + WHERE fp.[订单编号] = v.[订单编号] + AND fp.[工序名称] = @工序名称 + )) + AND (@计划开始 = N'' OR v.[计划开始时间] >= TRY_CONVERT(datetime, @计划开始)) + AND (@计划完成 = N'' OR v.[计划开始时间] <= TRY_CONVERT(datetime, @计划完成)) + AND (@排产状态 = N'全部' OR @排产状态 = N'' OR + (@排产状态 = N'已完成' AND ISNULL(v.[排产状态], 0) = 1) OR + (@排产状态 = N'未完成' AND ISNULL(v.[排产状态], 0) = 0) + ) + AND (@指派对象 = N'全部' OR @指派对象 = N'' OR EXISTS ( + SELECT 1 + FROM [dbo].[View_生产订单_MES] AS ap + WHERE ap.[订单编号] = v.[订单编号] + AND ap.[指派对象] IN (SELECT LTRIM(RTRIM(value)) FROM STRING_SPLIT(@指派对象, N',')) + )) + AND (@发货状态 = N'全部' OR @发货状态 = N'' OR + (@发货状态 = N'已发货' AND ISNULL(v.[发货状态], N'0') = N'1') OR + (@发货状态 = N'未发货' AND ISNULL(v.[发货状态], N'0') <> N'1') + ) + AND (@齐套 = N'全部' OR @齐套 = N'' OR + (@齐套 = N'是' AND ISNULL(v.[齐套], 0) = 1) OR + (@齐套 = N'否' AND ISNULL(v.[齐套], 0) <> 1) + ) + AND (@发料状态 = N'全部' OR @发料状态 = N'' OR + (@发料状态 = N'发料齐套' AND ISNULL(v.[发料状态], N'0') = N'1') OR + (@发料状态 = N'发料缺件' AND ISNULL(v.[发料状态], N'0') = N'2') OR + (@发料状态 = N'未发料' AND ISNULL(v.[发料状态], N'0') NOT IN (N'1', N'2')) + ) + AND (@自制件属性 = N'全部' OR @自制件属性 = N'' OR + (@自制件属性 = N'机加' AND (sap.[属性] = N'机加件' OR v.[自制件属性] = N'机加件')) OR + (@自制件属性 = N'装配' AND (sap.[属性] LIKE N'%装配%' OR v.[自制件属性] LIKE N'%装配%')) + ) + AND (@检验状态 = N'' OR (sap.[属性] = N'' AND ISNULL(purchase_check.[质检状态], N'') = @检验状态)) + ) + SELECT TOP (1000) + [计划号], + [合同号], + [订单号], + [产品编码], + [产品名称], + [计划数量订单], + [入库数量], + [要求完工日期], + [要求发货日期], + [发货状态], + [齐套], + [拣配状态], + [发料状态], + [装配开工], + [完成数量], + [终检], + [生产工艺], + [排产状态], + [自制件属性], + [预计齐套时间], + [缺件物料编码], + [缺件物料名称], + [缺件数量], + [库存数量], + [缺件属性], + [缺件生产订单号], + [进度], + [工艺路线], + [预计完成时间], + [工艺路线明细], + [采购未清数量], + [到货草稿], + [质检状态], + [SAP单据], + [SAP行号] + FROM ( + SELECT + 查询结果.*, + ROW_NUMBER() OVER ( + PARTITION BY + [订单号], + CASE + WHEN ISNULL([缺件生产订单号], N'') <> N'' THEN [缺件生产订单号] + ELSE [缺件物料编码] + N':' + CONVERT(nvarchar(30), [SAP行号]) + END + ORDER BY [缺件数量] DESC, [SAP单据], [SAP行号] + ) AS rn + FROM 查询结果 + ) AS dedup + WHERE rn = 1 + ORDER BY + [预计齐套时间], + [订单号], + [缺件生产订单号], + [缺件物料编码]; +END +GO diff --git a/doc/新增产品合格率.docx b/doc/新增产品合格率.docx new file mode 100644 index 0000000000000000000000000000000000000000..2ba05fc52b293d45bd4b4100aaffde5aa08ecf82 GIT binary patch literal 20326 zcmb5U1#lisk1qN;W@ct)X2%e-V|L8U%xuSO$4oKD%*@Qp%*@QpeBXR~{{QaoIeY7# zshXOp9(9kTM^d-cEiVNM1_Ste1*79 zywd>z035ym07(CtOyACq!Ohw#Jx0OSp9w8+GwDnKX(QWrXKoHB_||+`y6@R6#lg>H zio=@y+%#*BQ_H0eqM(TW zja|paazHTs#L|9iTrSnB`1-Q>uImVJ-D=pN9{HIAdC)aTn~yV5vHI|A;~@P z{b&U-ZrCZ2fb)8l%H4h3--u<@|C);4Upb9JFy7>tD@9BpwwwuvLVxiDVd=Z0$9V;F z{6)#5%`oDB#Ugas+(re6g%1!53JyUFf%NM-i;HHkUt@h zhm7WXkpKHG&LW_i9Hb_e$73%=q%xGEP zzJ~8o4Q%Q_iY*J^Y8Y=R%~;d=6f#`=rhk$>TgRpKFw|aD;IlA%dSmWL*Vd|6h0nLy z2m>8a>|V8x$JIj+*#dFmw5eQ+n3yZtBFhDcJ8E~A2FGgr zAT>dv^}VC<&3|(Uj#$c#L?8$kKoC&>3kc4RPPW#6VW^LliC$qs3c5^qAtc!pwyM=< zmQ>ph5VcB`Ph^8)P~PJTZ?wnj4tw^y#s3=0Qz69UT z=#7HTZ~HA8Pw)irpL}2MpjwwN>OY6*t`ZIdM7VSb^|q#@e<*m-9A$Ys8i! z`dftT+jQht(rqRYDl)?_y;LDr=a|1f!l%ZShsr1obIM`8p7j^X!%01ilw9_4+!8&T)ze*W+jMLisL-QH(hDb7%MM1l{93uzFKa|IZDJK2Hg2M)L36k+7gN!7 zZ@^_I?#M#}9C0AqG@d^)gB%$OuYMNI68`n2|8w{Q2g2xT>tOWXkj`kox-0~S#y(>J z0P$ZWj!y1Y#*TkcZr5IQ$Q{7&5>S4I3@hC0PPDCNt(eX;@#M}3B&1N9|qjR+|29J#%7U>WvDk5+e~Qq1T| zf-N>k>=mz1>y!4Pp9%OjKt0;8B|_qpnudp;{)!%v_7W(`KpPUE1}16Z5Ob=?ux~*8 zMd!VEQvUTS(Nt$NE5tn(cOY~Jd5I{_ihQO_EWFyxF0>S9uipik(O&7(rX6uvql8JB zWlJ4`IW%|X=}%~$A2P*4G?u zv1^?%bVcJo#2^|jh0Dq@`z#$M+?H1hr}x`D;|KwHEUoDEyR*=q_1wdcJ6kumEHPo@ zq!JVN*U6tCEUfX}?7CGXBdqTVd?hD__rq_^3Ewl^Po)yUg?I%=zI>wtoL(5lLKAkV zAN%lhZqtnlnE2OswiQPmvj))Ff_S53Ur`cn$VE`!Zzg^>H`IGBrGF)sBepa(ZU$+h zi}gIoOcO5eslVy}w2=vwd4K70tU)3EwCs;Nj0l!rm`60_#c(BoYi77VS-L$GC(rX2 zN_)B7P=>rTzDfwL#S39Cc~FfH8@3CX-9|F)CHBTgu;<6yG2rU6?IqrD7J`$siuv_c zPq{4yxRC8d_HB)G1lziZ#|LTp8Y2#Dy8PSZ4Q%>>1@b5Bn*+9dd~gss6#~4JJPuA` z784ttpt_lwf6i1D7lL$O1$tg(hYyFHR*_)7`=Eg^3cmcNCm;5+_+1 zLDEQ>{Av>2!x&02A^ z{0BA52*%J1CrG!;8tAMISla>5sp-ZuQo^(t%}uJZtn8Bo*sN+w^JWQ zW=<`#hFc=VW-GcFNvK;unVP`2=C6!erjX>Rg@wQ6!@~nGNLR;Q3>92IX%r85x42V{oQD(W&xDFNP%ddf3X-~m z%4VV9Ua<_Ib!={DHAO)k1clm|xY|;yGRa;$zumMaD3C4k)+t65J2c1gS!W}w+w3^? zv&2MRR-IZ@M?7}TTu&2{szC|Gi*iC%jgZ}(MGgo)j#^}W9CkjvC0%*r7xr(h@(Y^qmC!SjMTsE6^%rS(6(2})@ChxEE3#l^qeDzYo(3AScB0Na zoRdNk_E8T}E{QD54@&GWl7!e_955A3N}9j;Unkd~eUyqwVCo0RV(0*GP2jB-Ad9Q) zkFH#vMy#ebFGQ)PtDKYScX+YC67bWO-l@iuvmtK3RgiMjH9$7;5+a>$6P`!C0~h!~ zp#9;=0OZ`O=hZDdfbLNf&j>xsRM;)8XMpgYBTHa$7MvD+hhj%cj2U08M}VezDz(LE zruNwwEM``bK98>rC6g{e&o{E7KezikJ>}4c99&SfJ}AbxkwfyImUdxfMU!4UgtoPd z1;y$|gXWR;Ws9!5+2-Y8lm5k*XtocL%d%Sk-F0to3lN{JY^t3V_9Y7*fz`|}>WYV* zAAfq*d}CyK9G8sNaQ#Q5AP6l#`=hUARKHjXob`RgyaO9Lm*1A-auR&t_0)FEaB>>lNJAe8 zn~E+yh6oliNU?;~tw2`LZO`iee~sB4!kIW)03TV<0Q{{{TyRhk{e}dI>$TX#D9`^T zd;jB53?BAqwshh2-&%JfjjKfq<=U#Xu&xIj{+DpoA`?L29RA8v3zTK84_C?`*_JLz z1{X)h`mg*Hi0}%UKpkA{L~1D?QEjMUX!^SJA_KB&u%IObA;fGl8e}6;#`X0UH85-OrmMEoaEd;YBP<?TRjQgt4qGFg#1U*#SN32 ziI;N(CFCUQ`S!~_sN(19$<|3YKU=UXoU~T~f(c=1DMu2ls_mC5+!{S_X4pF$O|Di- zqr!vX&-35Q8Gq{3c}#Me#6@1qN5?l-yhmkS=t>{b+-<~FAPtm^7jR&91Ukh~bDe3e61mr$xm!06kl-01T^IxHYiB)2e7@8+s)b&Dk{R6xu%QOGr35RL%P z)xfTAm>^d?WzU`R@elrpY1(kCFeCl8!eCJ5w@VPuhF&W34OJjKNWARJ&_k}U6*!`c zb&99aGGU`~%bLgA&;xMQgAQ(3_09iv7p7;AfFix)%Sz!3lp_A?QgwjPBipe`?*zQh z{-;>I7kX0Jl*lWKAt>Hi4##3-wd7bRxkp=rb@a*#p2D*2PL{>7eMCt&H4b#jx^>=6 z-quovHBTf%6{l`IN-jsKpduY7$AdabzpTQRd)4aUNokFHZoP$(J1m&7SqHgW$(>hk z;E#s{{pH8Gb}@42_g@l3)yLFLI;o;wM<@$<+Yd2l&C1SDoatco6!a>mwI=(QS@gNT z4%xG*U4?FhbJEn*4L z5-_bFS)7%v^FpMO$) zAb+UQ(s4TBj-5vt&g6|R!)lG(z-IUpuRp_mz9I0h03?!9Y$ax+TX8VHF@;N9eacl; zn7~e)p!YV`4Y6H+OK1B@3^( zM=ljdN;bUp@Up*9t)L^_mij3pl8udBj<;!u8Co_qsVWWO1;X`WS2UbTLN#bu$>eX> z(ZviKX7fYzfWiae6d|!PWCO0LJbI710x)&|cgs|JL_8a{FoLa*EE5Kfy~^K0UywP7q6{zHT(8ce*jZ(- z%KZ)VC6&$Rg=2o6X8#CR%5ylb{4O;=LpbefvT%y+u?7`J^J{3h^|ftt@^wPILd)yV z^cI+-pxOo;EoLrL*K3lF@j?{DE$opRT$d!QI@1kB9j?>w^T!MAj{uh7J5w3)>A<&?q2~+g*K6}dBX*JCn zk#ZaY%E%ilKVh1Mh%%JwWisHTa_cqP7t9h~*nLNwwQO4#kJu%>aD2r`p=O_Uj@Fhd zoL9gXz9eT7thc9IIB#}qzA%gs#bm*{c-j_D)t&h~VAc&WqpJn~1U9~SrX zH9GVC;WWvc=`m+uftlNtW#dvM7NTZYy@%sD99s@1hAJUhpe*=J%axH_~yuEo8&G z@g`1K&Ukv-@c{LVr^wsn$kxcI&`B4_eOWJ$T54(89mVDE)w>7GqRk@E6V-5YoE+Ut zsOw%rX>9~C$fo|0#&(%t)*@}x*uS%T3-YHxhO-zPGXvypDLKVm12}R!idvugM1@p| zPVBvXi{l0?%_tNO6uG})*Q0ue7@auQ2pp2)E~28)r0b3N>qG=z4X^DWRVv@%G6}sI z3*_96i8_3z;7<<@Va8oHj*|_mDMnnSbhj`RKt|1?f{9AL>yG}jN_>KS;(HUh-yv0{ zcyU|UjsGX3K}yQMh>`W8c%OX?@8jXnDWZyiooP8eIX&iW4aA17Eqxl^@MgbJj*q{y zbho8Hv{4s9CFqV~?ZoVYi6G9^hsAZ8PGDdP?sRlExcg0?DfseTZ)0xK)(4M~k_pbV z9+~Z{b^GPS+v){#b{*p(8X-*kEk@N*-|N*6=wnt2hDp6yH184)h;syn?V|YaBH7f) z-SN;|*g?3;#fVOc>p0Ql!! z>}YXbcn_D05!C71ECsOhJZU|fF;!^vDloE+t#53IvfDp}jH%$n z%vRtA?Jxo|m(gy><_N&2!EBhsVpCf>pmhthh8R$ai(3j})$v(Km=URlQ?{duW2oWA z*_AhF4?m=4xxh-zz3I8M9?m|eIML-c+Z3$*k{A%L-6F(iObYJB?7Mj}a)ZWwIo{d$ z;e(t8Y)P{$$V=GJf(=Qw_H?6tWlunCN>1u?UXw%+xZ)l|q+h91daQf7QDLXe!{D5| z`+_DIv}cT~+5+XArqdkEB?60`ZPjPpTZa7{2lba?gE4? zaq}BO0RZ9(LkM zmo=duZGiY*x|~oxCHMWXzz;&w#_^U)Chj+f%t|tjgY62Eih zt3fE;zOJe(wTJDdgoA{hZaRw1LDEJ3_auyDKX@rmQ5a}{)(>U!u`)CDInIgv#4c7# z3V%zJent%5^tl9;qBAV67;YH`fl3ccBu0NuF~>1r`JSIrMw~K*7OEFUYa-O6fuc$i zMn*|5Ju>VhDbY+Gp!dB1Z2(vJC#b>(WZ}I~Z%|pU8oD%_(F_>Hd|uFy)jAg72!bUc zHizZ_uS<3xSgaXZ3}twMf_FkP&=x@?{vp1#((ffJKZA z83;kP@FgC{19^ICZi{aesfKUYS>i$*Vi!!EC=5vtu}S-n!UK5s2 z=Py7-5L$b{Qa4m&m88UZzmhI17RmPSW`ecHJ?oYE%c0*8f9CYzjAFN1rUeJ(5g^a= z_*eb<={yMk`*=k|Cd>vV3<# zbJ^jRL6K8&mX`kxzCuSlsxA~|2+@NWa7nX$gZIjo#Z8M7k`-rc=hO3tC?Yzlxe{yk zSG(X_G;~>Nd~IJ!PO7Mm*c@Iq%uY7A!gmn$CB~HVL(8w5+AGhyx@FBAIkVa+0U7Q1 zWLx@}zsYbjy%DN#B*4#t+&YaTh-c;tNZN7ghF`jtv4aG;<__!qs-x8|^W=~`A@1;X zN$98XTx`l#A1|$J`RgjR>nbO{J~n9R>UuY`+X{G9y?Y+-FZkci2RxjR4q(k1M!#+z zDMzghWikC2f~j`EgN3zA=uK!ZBzZU&FZbC57d2;B)l}_V+i0q}eSc@D2h4I$H2fgh zVj1HGUCXD=<5Gf6&;o2jB2T8A0(3?GBeXgx=1Qol?<8u z_z0LyFImO@Gniv=>=`qee_Pz67j>A|Op-}BwqHxV7>t{vRXh~y-s6Fu_SM(l9Q;H0 zNqs0kTM9a>;FsqVNY1%=54Ba|4mZ9z5yfjOW_jQ!-rOilLYAS1tTAh{Lkn4+L$W7_ zYD|o;d`sGR_M2XQ{PkcWzlF5FlVup2AOI$h5DowUAr;)}f-7YL-_dn)NS#vilS zYVZZ*?!R!p(e$n=lMAm|zV$}o5C@7PYNg)=eYd6Pk|(Q`HL|;xN7?Iz>|)#++S5vr9qiC=y>E3pXMz zn^-FyC6PxFBU3yOhVFLHHuPth^QJ2h*WVylp7Z3}&NIxknp{XNcNOZC2NRO&d<@h> zZPIlYl%Q>ZyyK4noIx00+$;czFo}h<0%7tNdKVquCcV(S=%T7;0sS;j{MRVog#IWW zJ?8k;8mZsEF~w$f4UgHfkj2z&x&7m-!jf%WK?mYrcX|A|>cBGh2IpQQGu7{^+U>LJ zpQoBTF6h{IziqEWqmAi%JSTC8gpQ}`^ex$JG$vK7%6%H@zFba>>uS<|-o@|iFYG+j zwm!TV9xkjXDE(#_WMb~-75K4Bxvp?an`B4V-uc3t zLuO|k(vvD~IMGEhvPoXY6R(XY zZQP=gIVz{$ysYuG+7PN3Z<-8yK=kPwc>PmQ*(QY_%INJS=^pu zN*-al+#ZIFij4XYxs<_bHKm@@cEU)J3c`i4I{4 z>r&ia)lkY}ZTl_~!+=o$z1?x(;ee1?S@V;i7=y;F7i%ra^kRvyEK(sm{vR z#|-@GRAyWKRnmub?Po}<>x)2v4N=d-Ys_nxXxDTKo$OARKmzTA-VJ?T!fsD6YKDr; zNS;4BqyEX8t#J_M2woGPzj0AnxiYRE)2@1dmGHZcZ9RD>1!PO>+tvLhyxi3*qEnUE zX3t%=HYJ+Js#r3IF?vmhnz`A6v-mW%faCtGc=-C03v{~kb~WK)1@&-YaZB$!v%~IU z&BcasNuYvjvvOt9yYbMLr%|WQdyO~VQV&~ooOX4xl9~I(JyzRV|G;4BEUYebs2oYl z1!k6P)@GvTgMCMi%NqeY%-r<3TKkQQ!QoSJU5QWj(+{dHWy$w}j;us5kZK-hbPdO#*oMw>rSN~$|6igiG63A(GxYlIGgn3O}qGR13eqR=TvEe>&TKw z4F%XL18{?S>b@k4i}I5;W#!|Lux^N2V)DonA|Z$}&f~%Wrr$flwm(7s>xu*#$-@c^ z6ad%-X1gf=%41DzZJddYx0u?t-lDin7^-!6J!mZ@*U->^{NG{vdB?i@nAJa%`N^mX*ni*m4#(Ct7= zK0g@^ACr(|F`Fbtm_iKy@!Z`LsX2-v1S?h=X2srAskM-DG812JwHPhXMX!CzI>Twr zUSZFAa(4KSLk^;`EVy*R5Bncoxj61=MUQcBL@~US;J8&0=&Y0CM?>jJ3av^p<|8OC zLKLX7qWX&-VJ7klFnlJ>I!dV*KdfoynN(S_HF}fXRTg%Cg&JeyS)uLFDf}3% zwjaf-2$N`Nbm?}$!)xA&2VFcw1bSA$WhZyg#XZ|Vgy(-4p?Kbwqj*@qC$jV_4XT(r zC=E8&S!=J?`4>)6=$EHwJItnx;`oTrnL0I!9F{bciJE1S5-aW0%vus`#vM!%=Gtn9 zNE6aOe~v&-nyw_}mm-B4BetS&1^Xi0`+{W>K#%lQ*%Ogd7ALo;Bh?oF=06<$4jbBJqi7!!{P~tT^UJx63T-nmEZX1j#o$f7h1*;rf zCO|-A4^kIN8zJ1KZrMu^3l+BD0>K`CsXoFL27_7A&LInnKe>QeI!y4yqOFp zGaM>gYw>LV_~hiO^YjlF&-$j;h^ zt(rJ6Nl{mQ1k;q*xKt{=AxjN1r-)sV8c9V~nXj#2L$6U%--Pc2?BtS|wB6RprMn`m z8LkgcqdjoVPCL!A7CRX}b-X&CACMzzgE0BF0=EO~LtiegnRHR}EjK=jZd%`)rfnI} zYVSg|wNN)771%FHUiSV!&L8}{NMvnnWUl|;ibU9ZodR1#0Kh8n{&$h+KM2jO^-YbL z8SHFKK~{;#HbdoQ#o=La{+@Aw|1Kf&0{{RA;tQyU0-jU>1bG*J03XnH66%fs07Bp2 z8zg}i0T%!u0(=({RB}r@UmuQHjXbFRrmwt%j!Il zBSmiy=!SlR`Z6it^T`Js5y0`Vd+ql2aesScl-56Zn6w5p6oQ=*S3WAgBf(+ibT21B}P!2kpR@D+YjW4V>z z&Qy8r?Cgx&>|^!z@j>)SA|q;;{^xsO4_2R=A0wME7A02c%WU(Gu4AcLBxZy;lu5F6 zI58P;3_!3)sNfz6)UbpgQb~wFUr=U2I8F~zcT#tbzr1MM8y6Yz(O=$8(FScV3PohS?F`(# znt!5w`FkkNj%N9T=%iJl$Q)83gNxH+EioG}XzI&fz01rinpp^Rf`rhWe zFTgDu90H8afHavUO5-(lVVeo9-e3o)tX9y`^Pe5S%@BY~Rh>Y{f*7O>s5^xzS_H7g zm-eOdN^=|uE1}mY-bd0~_rk5FD;!v-1lS4vMIJvLShoaheR%T{L~nL_6Qsj6B}7j$ z7NW1sYs+1=+AJzm{K-_6zD;dCWvJDL+gqad^7KyF=m&NJsEta)<#d1!EmMDeiIsNo zYqr}_ZmIM9n2eogx7MCDVuwCeqXW{>U6X#4I2VO?KR&v;4;+IvpV%;YRE@ptFXq*n zEKO_ua7;H_FkP=&I_}v`8;&HNsmu9^OOFBU2@#4V(!Naj%nqu*chbI_Q!t9hzc?2M zJAb_Wx>k8DR<1)Y2cfcq7>KR83%)Bh57)r+t||e9%eOwy5XrvYXO2zUB+KI^Yepw| z#i;+Qy0h--v(LVeKLz5jnN(U2*X=H2fM`Gb_Yvp?gumU+e=&z-VQ45)M;0zO)3n~N zjN+5isjD`F4Bc(6trB*F4O5^uFLFA(wtT!}0vRl7JkpL3l&OSob_E%M8E3{AVK1Ok zx~Ij&dSp{L+Q~M_g(=4h(jE0OLep6b@i>BF5d{4G4|;nak;Z9SEu&!HNA5_ z@Y8!>V8VIR_nxM!Wh}w0n%;>t<`kqo9d5X6@W0?{0$t$_KDgTAXNq!Ei2B8TwTIqx zU~1>O-Jfe(tlCOLuuB6h3ZQ}bI_D1_jJ>xyM%Eo@M;PU|)ZDBo4KlRp&6IcGi@ZzZ z%y!TOz{9mvM`$KVx7MKr0SDL92CCXJGah%D2ivqrn^Tn8;tNJMn>}juS`~%8X<}dk zknL~5=r4Iz_1gQLZySQ*I4`jp+>18aOnWUeRGdvn|1pfmAQ27ZYuR%R?~D;QT(u2i zQlQaZ!SH+QVJhQrqm&39@MlXy8_Xdu5MLB)op+b3DZkF3j%i|-o2_)Yq3_?#k?Hkg z1MOc=bbBf78m$=u3V(8JHxX8*mNG$n0q&=Mnfjd5Mo*_quI--6BAeIjw~S$Ia8lr~ zT=JhwX`{I3jM#BG-o&-pzb-OgR-DkhPb5~YdK@w}75~O(SiaA$MxN z_veed6U)TT?yZy!*xq-@WC%`|Mbx*7Rp)rxgG2P$w}Xq8Q7cSPZWk%SOx=Gu4E$TQ#H8CyElVgZ9rxpp5M&jTZ6HuAe;X0+HUW^PnFibmBn_S~YJ-^q48pPue< zA#DZ!+4HIX(P75WaUsHjJH71pbb=R&%EkIxY~w8Ro45>wEai~3$6D%vQ*!NSbSH1` z^Hfr1V1B!>Y6`w^(Hxv9?&N&xH#f@!*Rcg)oTa@ST{n~(gf3E7y(o09eBi8d_O`L# z)Qvs3=*_9W#1j zuV5cBx|P~w;O(L`iBX~@nvI2o_a>9f`_=wNMTdaEd$PBqhFF=w@uboCa8$uEq|oyM z3{gC~eN0wSO;;Ad1aCI(jsJ1nnqjDUNv7s*75V79tmgsDu`?1kT>puR%Hz-RP0Sc zh`7kd4daKmuk9DH@Y)BROA;gwL-2Rs?Voggfb`)@vl3G+sPOO7$>Hsp-t6>h0Ov}2 z#AO@%ucc96k3QU+dJV%yP+72LX*RKTPK8_>8m(pz8iwj#jK7#7C1t|+w`k$c1@a3}Z{;%iu0m@7-!eEzoEXwrU67tg`9P zHfgTCu&bv};FqfUASI0bI<5?aPfK@e3F~<1F>Qj}#w9j~2kp;Ro`H`{m zQoUf>Z#QA*BeUm1&&^jCik;elHbXFtqgur^$7OVByZdt&&7&~I8nF?7IV^`KXwnW; zfir}z;RdgX z)a0^MUw(LaW=UtyTu03}3@bi(Zny2+*}*&acxI5+NWq&XHCD_}rfI5iBbw0D*B$1c zDVyMI=Y2g}(tRVTdXp_v5uxloQ14@3TW=w*PAnjY;tdn_gnRy&)q`Yd5xu^0S91?0 zFjBxRP_a`qs<0oUqK?Wv>@qK&A4f|cOnfo@#Q@Dn$f0+)IfbI4+BER4LdO6pK?V_q z(&ZfsyVjE1v+!X)t?|2*+?R%?KBxGqQK=!mz2dPkDJ?P1@w${7Gc9qNLtZ-w`|j#{ z?sGp=C+;ZeQX%h*JcG90p81lfoY^|>v=|-(7edQb` zx`R;ue>kxyNEZ!w5U5>(Bhf+|A5a1$2s-Z1XBYTV;*bm85kr<6>Vxx)I0!k~o51Rq zmxHyN9fX?^wA9h%2=Xc08f;?B1(UeD%c(-36L$l;CM+@*AP6lOESqB&cJ5TD1!TEa zji29u_OHa*flkXkyerUw&LI8c{h6!Xi!&k4wMskp535$x2;<5afAlat>yzD(%XkHq z+Z3*?15!Z*Dn=b1_q@F((ENjCxg1yCy~o#%n&26>3R&((=i9IXG)} zG9#B+u9GirZqP`rCeUm`@P?kV&}V!+d&9_^07cvP-A@INyoX(Yh+6A zeoA)OHL4(ECCh;Rk7OL=UHGIzNGCa-4n0Y5KG^oj}mL0x0RD&@J$CY9mT*|1SK3>~{{*lUes z6`K?#H&rI=B_7RdOoqIhwa`_&{zyadW}8Nb`eHX{sgfoc)qt0Saa+sJH!W}F%Z$dU zkBZ%Csr_pFF`XhF44c5fKuSer1bw_8rxW=``dz0>qYA-muabgv$7HMXsu$}y)GvW( zD|ukcvAiF!3jIcWb-&>nJNfhNnGJ?-n@vWR0~d7%U0Vwp#V%Ym*ELid$xnKN_kZ5R zUYJy4^lNcNI5E%I6)rg?TBVhBN;u1{3|DBxY}5f@pX zJ*zBM>#!Rh)QLJdMcdDusM3}Z?N}btIMt{q`rw&uyiBR!w((id@cH;x!uI~|#!JxY z^Ue!g?Ok6#lXHH#$qSGUz->K+_Fg>a89~3j4Kw$4bX_-Y2=~Kl&5xd}{EU+Qn|xeh zG=vGVIS*ZzO|@Sg-w948$-wH*wKyh?c@M>cEWNO-vMH&^EN8VXja;saJES};4w!>% zt)Lh>Rv0vpE*DJPnn2DK>!Q7mIxFFNs_XRhtXpj1`67%mZZ-E~{B){3+ox4+k#JGE zz^IbnFG{Y#@m1ICCmMOL=ZLhQsUw+w^pcj!Zw4WX%cVUW*k`D;OwbnxraC9(4j_zl z?r)7ODB7KGS~aGMD3zz_mpJ95$QTeQ@C9I7P6%jD6i}d!xWN6&1gF478oQZl_?d)cIX zbB$r+R6iF!oe*miGMj9p zjvu8|R1G;kQyKKxN5qfwEA5+U)=m&9X_ID=L#Zm+Dl`_yzJ66V?%40p%o0hCfgvepneb)C z;|G}=VLn#hO+eOe_48AjwL82K-4;gyFk$Hx?hRg$@^R3MNl7_5n@Nc;WiTzBpW`)I z8=|pgue@h!{yNuwykYe-ozgs$^xP`g$vC9Mb{pR@q4J?{q&=>P`zCI>TJK@6vlh0@ zN59s2c$8b?3*<(R8|tWSpH+E1m6}`KY#pA>899W4?k8cw=7TvrNMAee-j5#)_A311 zUUGp4vw@6|``ECSbaW-XR!t{X`XLGo%KPH}v_Xh1Nt-LW-%f8*$#B`7%3L3`%(Opx zax3HmWh=Z|UBF(?22+gY(l7&OY5v3t?#Jl5=hPqA&F=bj)Rq8U)R5)02Uh9??2sMy6S!@sLu_F5;`Di?obIEqZ>5D zm8_;(d$#@zvP$Y*v^ZqJ^;P4nq*)!{q_^Ily{yL(?86N1IJdCQS8jM)8=h}`6quN_ zQ!e9WREbXR2Wv&t(6~7qofBprNA5#G9VDqx|dd!Nh zAMzOEjY-PIRp2Gw*w6)?nCRhW@G|c7vc(oM8CKw$cWF`XSby{ULwvZSoZRb}d-$$ic zQKeJ*dJ}G71sZ3y8~ly)y>M;ECU_z^2(Z*NKwf)DA>nP3DLJ?LpzACFFeoSW3}z*F zJxIJgBk87o}nBbzco1!|;!YbbP(~HQphL5^uKt2*Tq8=hQUf z&{X|NQ=l$rEUvh#=HxYKrr3S7(cN&o&@VXd_M!)A9m6{LX`W))?|l&U6DehMwf=^; zu`*gic2KgA^1~|MU|l(>)7Bb0zVvNxqC1Kb`kM3JI!0xABc+a>+uNlHqrJJnV{>1u zEDe9O7a9C;JHD;uf=06~4R+m3P4tODY^~3JMTO(Bxh-k|wDiL{x1cd7_L6k{DQnVs znX7$=k@}QVrjslVb{BJjac>E~U6PmUXqL>)tN3dF>GF&wB~ejA&K=d?OM#y#PNw@6 z=Ol^KnnS=+1^EvjWWd;1zeOrTGyZG7Ia|(gxI?#JjAcJYVOyIvK6naI1PURqYx~3_ z^;wz1_V1-;+Wf#u$RsJW6M@s%%({|hJZ;&*$R{!f(T)WY<41=JZFWN%JWSFIl8fSO zCi^n^O(=@eXO`z8dIoz2t2Ga9884E(iRYJj@~<$|hdyn;fN!O2>7_xC$+c_7JJuFpD_Gig2cY4-Klm;`_023#ILA6|Cm&I0E~ zz}jZ?;O_P7;$&`|JqEB^;6O?w$1}v%RNb1f<+@&xtHmr(`R9Psby3@-6>F$k^X2Jn z#as&x*mG+02jpSN;J^{S-3&~ z1XcG>$tbv#wxk4cD9I8+!WN`IO|#m{a9;otSR*>Uo5xIvfg~DC-wx7YqycH&@=}N= zCxMdQGHUu-5;sv8at+!=?=lyu21tN!3w6?obPn*SX0LYiE*N&A_G-kg>{1)eFsMla zi&{*ui}SAD=Oo{OLqmZ_5)Ira)_hC!bjb_zkPYkU67AOybjS_5?zN&KZme@?YTy@A z_+%JJMG61_bowfl`V@kW`(_cZ`_e|#=JW}GpeUvq^of|~4-+2huC zH)tS00Buk!T+%*aQXZ)t*suV_S+1V5R`g+rpE9;;Wq%H8j1H4r+pEKXddg0@=x{(C zWIWwCn1%-gO9Y|&<4)COi|8xBUW(7UqFWYJUM7+}p1%7d|CNvmfn+SDBP&%C4d6tj zIvRKXpa0vpKCldxAZ*A6 zKb)LO@%Xa+2lca%sn1885?FQ0jk@Z#4ig8Yjo&^?M=dC^I*D$lrtHs+ z)!02Ov(5eDtq}SO1t21JJ3(P{`6KJ1g#+S-Im`i7Zp%|PpOsZF5VCxEIX9-C=mKO_ z<3@cpouI!hds}el4z#OY8dn6ZfLiGzpj6lL-6z~l(0CB(wBn9x1*iqqjg#lG_T}g< zbn?MYDhU_vWUZbskPxoAnAgTO?nXqUa3GPo;cD>H=nd!oB}kUerY=K2RUKguDbv69E7#vai^z;^s3*tT_SkN8G-QCPQ_)x!g z?_l&V>z$z_2O4h`Br{Mz`U`Z+hRm{7*Svd|or-CjO?4bVD#~9waQa2iRH}#cl{61f z_1m5q;ETDr8GU%myuenN8RriridQ9X-k!6@VROs__?&^+^Q$~0^~)=aNfy{G1vR24e1fIfn+_5ugzaoGWz@WUlBPm|P_b5>1L zYB6JhH(4LnZiH1K{%grtneKzyLUy?9**UCtPKPtCx83H@Wdn64qMzo_7TcXP9!X9+2W=&_*Fr>x!o z`AhK+H&b=szjp4@=c32Cfg2b4OhSN@zrh50xSA?iK3aU1l+Fc3~J$6V1O$U27&18;2t)1 z0ekx9l6V>nz`qlTu5MuQv@zbb*9TsG1;r|@{m?^n950*L-TXmxT_d4od_{^`> zAZv38u?V(Jc0d^6{6M-;fRcBGM@@mcqQkL0dGb3;KzE@G0Cyd9z=Ull5PGpisCIk< zB~Q`8vxA>%^}qo5|G*-Q&-(Ng{yW@&?MW_rS~r`75}x7xtIw=JT&8Z)bA;)y8eBpS z4LCu+zk(T1aSv7pG57tBV2}6NC-ZMtTvFecR3c`|eh`gpCE(zZ_EZ1gP3DASUQ})U z@v*TMbfoUDaf5*bGQ%O?p(0Nvyp^$e(B>tmI z?|g#>7y0G3OhxLm;wYGHHX4uwJdUfNf4JXey=;<#vdN`TQgW;1t6)Rebjy-K4Tf(c z2D;al=oCWE8llLIYOiC4mX~J2vI5i2@jRvZewAM%3DD$zIXI6sNrm(Pu+tQ05lW8t zbkAcD5OCcz{~D3m$`>K_ZP}B-1H8J10Dv#cUxy{;#u&I#mkO4$gdv*yh3l`t%ePiA zppBTSC!M@%g;^#64Eb)zY(7{42!=<3SUW8mj~d2bq0s4h)^4hr_r1_StqAIDFEr8 zS!OPnfW{OOfb~xx=;-V$wEuN@tImqhbNh_u1ptghj6(zcQ3$$wlNpW~0;gaTOfbwo zWji1nPtF*Jrp6Mml>Co56eVF8zza$kXhhS$^SsKis*1CKyC{hW0Iz>34QSt&mzUWVJl<-S2D0Qwqo4p6qJMByo?T|3;pP^E{Eq>D z1&P5=9@bLtF#SKflK(jJN;P9c<3C^-)bb=kqV=NH*8UwV$t#%(bRcPD_Y;W{iN!o8 z4O}+OcDCi4Ghqia13S17K2mzc@XLhR%M7}fOX)KhRQ>z;`~3?OP^;zpcakT5d%78c z8s9jA+8f=wC!Z-bnE59ze+q*GD8woP<*QcA0al$L@9g1VyVBGC(5K37{vv(`hnX8K z85_i%H57kXw<#WTIQ(U{f`_4>agBk^bIVY->A>n1obwmPMRl06D0XJrZu=m-e9=WN zhIUX~J30SI_+@UM`r%RA0%nE)i1|%?$x{@?`#JXU|C%JR{HE&L5Xr^f?&>TJ+m&I_ z(WT(yEEIR#LeZMFff-Wl$*G<;6*1@B_wU~Y@-kK})Z~rRRM-FvUEPmOR;~$iqvN14Dx?$ZHG?)u1qC zVE6_KM`&yUC+C`hxq&Q=hd-acU+=ygWY&)T|Jg5{^)ue`S`6GU_H^}gS?83{gnNSx zXc{`cC^ZND+!{tDCHcQVxre~{N6`EoM2#Lu<=RPiy_gLJT7jpeD4wY`zpbToDJS3M z#axft2F00odGG$2;Ip;1y19PGhIM;C6d9$Tt0_KFRb0|sv2aT62d-(MyiI%fj{WjG z`1xI8A-9roRkQPlB@bLA&CWhO`m2-eiP4m5>CGB?cG@pyKAt-z^7|8maK%abbInxR zV@_Q;*-_Omdonck{)sP_nP*L0enW~iGkcxm8^4V?|884vS$nla{>#CM&pSnn)@YoY zVU@(XUQsgBj(v3#PtmNjQoFP7r+c~gut_fE>l8DbI!EaCq&MaPiIqC%f5sZJZ?Tcj zsQD9OQGP7VYkKT{C+K4A>i6%y^_RW5A62)+^V!CBOsM^EMunL+`D(XQPE1F%Mruu&;>CE#aL_#4OEN1EovZD|U!~iVZoi{`X&Ly}7*!$@*&iW>R(zn$Jql$W1rd zqxNxI(#^kBv0Yj-%sl5G`x)ojAZ0D|uy*azjxFZ(7VvstsZzvpAm^nukR3tyE!M_57re z)0GXWb~AKi8!jKd-8bpilOvXH>3-+m32`!D{zY<-i%Bl42a{c(4z>Lv>6x~6o6#1CvfQmW`scu0IjjY zJVpyt7C`{0(A@0?D|OH#uSPokgU1yT&L z57-YyXoH^Uh3;DPQ>PHRHv`i)+)~&XROs5#&r3pRw*ZzU2<`CGlkj;On313W_56HvVBL!6WLjXt%s|QNih3;7NVh*Gc5>k4o8Zinzbd%6`=^#wn30(dKb~UmY z=-Sbj)FQNdD?zoREU?8FXs97juL{)9&Ua@#Sl literal 0 HcmV?d00001 diff --git a/doc/设计报工任务模块.docx b/doc/设计报工任务模块.docx new file mode 100644 index 0000000000000000000000000000000000000000..1025f553066bb1b75db46ed0b68b1f49e0ee0a55 GIT binary patch literal 42889 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 QNe~^ZhPV|tvTs@c4? 0` 判蓝。 +4. 修改当前页判色逻辑: + - 新增 `isBlueProcess`,与生产计划跟踪一致。 + - 新增 `isGreenProcess`,与生产计划跟踪外协绿色口径一致。 + - 新增 `getProcessBaseClass` 和 `getOutsourceGroupClassState`,复用生产计划跟踪的外协连续分组判色口径。 + - `formatProcessRoute` 改为基于 `outsourceGroupClasses` 获取颜色。 +5. 本地模拟 `7134` 判色结果:`step1:process-route-blue,step2:process-route-blue,step3:process-route-red`。 +6. 执行 `npm run build`,构建通过,仅有项目既有资源体积和 Browserslist/caniuse-lite 过期警告。 +7. 更新推进台账、任务矩阵、验收证据、决策记录和总日志。 + +### 修改文件 + +- `src/views/PlanManagement/TimelyKitTrackingResult/index.vue` +- `work/PlanManagement/TimelyKitTrackingResult/03-推进台账.md` +- `work/PlanManagement/TimelyKitTrackingResult/04-任务矩阵.md` +- `work/PlanManagement/TimelyKitTrackingResult/05-验收证据.md` +- `work/PlanManagement/TimelyKitTrackingResult/06-决策记录.md` +- `gptlog-process/gpdlog.md` + +### 验证结果 + +- SQL 验证 `7134` 的第二道工序“打压检测”有 `收检合格数=6`。 +- 本地判色模拟结果为两个蓝色、一个红色。 +- 当前页无 `process-route-orange`。 +- `npm run build` 通过,仅有项目既有 warning。 + +### 下一步 + +- 登录页面展开 `7134`,确认当前页工艺路线颜色与生产计划跟踪一致。 + +## 2026-06-30 恢复外购采购状态采购员拼接 + +### 用户反馈 + +- 还原字段拼接采购员部分。 +- 不要单独的采购员列。 + +### 执行过程 + +1. 确认前端 `src/views/PlanManagement/TimelyKitTrackingResult/index.vue` 当前没有单独采购员列。 +2. 修改最新过程脚本 `db_backups/update_timely_kit_tracking_result_purchase_order_20260630.sql`: + - 在 `SAP缺件源` 中重新读取 `s.[采购员] COLLATE DATABASE_DEFAULT AS 采购员`。 + - 外购 `工艺路线/采购状态` 文本改为 `采购员:xxx / 未清数量:xxx / 到货草稿:xxx / 质检状态:xxx`。 + - 不在最终 SELECT 中输出单独 `采购员` 字段。 +3. 发布 `dbo.生产管理_及时齐套跟踪结果_查询` 成功。 +4. 查询 `@订单号=7321` 验证: + - 缺件生产订单号为 `4111`,来自 SAP `在制采购`。 + - 工艺路线/采购状态为 `采购员:张丹 / 未清数量:50 / 到货草稿:11209 / 质检状态:未完成`。 + - 预计完成时间为 `2026-06-25`,来自 SAP `采购预计交货日期`。 +5. 使用 `sys.dm_exec_describe_first_result_set_for_object` 检查结果集列,确认没有单独 `采购员` 列。 +6. 使用 `Select-String` 检查前端页面,确认没有 `label="采购员"` 或 `prop="采购员"`。 +7. 执行 `npm run build`,构建通过,仅有项目既有资源体积和 Browserslist/caniuse-lite 过期警告。 +8. 更新推进台账、任务矩阵、验收证据、决策记录和总日志。 + +### 修改文件 + +- `db_backups/update_timely_kit_tracking_result_purchase_order_20260630.sql` +- `work/PlanManagement/TimelyKitTrackingResult/03-推进台账.md` +- `work/PlanManagement/TimelyKitTrackingResult/04-任务矩阵.md` +- `work/PlanManagement/TimelyKitTrackingResult/05-验收证据.md` +- `work/PlanManagement/TimelyKitTrackingResult/06-决策记录.md` +- `gptlog-process/gpdlog.md` + +### 验证结果 + +- 查询过程发布成功。 +- `@订单号=7321` 外购采购状态已包含 `采购员:张丹`。 +- 结果集无单独 `采购员` 列。 +- 前端无单独采购员列。 +- `npm run build` 通过,仅有项目既有 warning。 + +### 下一步 + +- 登录页面确认外购采购状态文本显示采购员,且二级表没有单独采购员列。 + +## 2026-06-30 自制缺件显示所有匹配生产订单 + +### 用户反馈 + +- 同一个生产订单号不要出现重复。 +- 同一缺件物料所有匹配生产订单都显示。 + +### 执行过程 + +1. 排查 `@订单号=4222` 当前结果,确认旧过程只返回二级生产订单 `5960` 或 `7142` 中的一条。 +2. 查询 SAP 缺件视图,确认 `4222` 的缺件物料为 `22-103-060-YDZF-20V1.0-4.1`,`DocNum=5960`。 +3. 查询 MES 生产订单,确认同一缺件物料同时存在 `5960` 和 `7142` 两个生产订单。 +4. 定位旧逻辑问题:`detail_order` 使用 `SELECT TOP (1)`,天然只能显示一个匹配生产订单。 +5. 新增脚本 `db_backups/update_timely_kit_tracking_result_multi_detail_orders_20260630.sql`。 +6. 修改 `detail_order`: + - 去掉自制件匹配的 `TOP (1)` 单行限制。 + - 使用 `ROW_NUMBER() OVER (PARTITION BY m.[订单编号] ORDER BY m.[订单行号])`,确保同一生产订单号只保留一条代表行。 + - 同一缺件物料匹配到的多个不同生产订单全部返回。 +7. 发布 `dbo.生产管理_及时齐套跟踪结果_查询` 成功。 +8. 验证 `@订单号=4222` 返回两条二级数据:`5960` 和 `7142`,且同一生产订单号不重复。 +9. 更新 README、推进台账、任务矩阵、验收证据、决策记录和总日志。 + +### 修改文件 + +- `db_backups/update_timely_kit_tracking_result_multi_detail_orders_20260630.sql` +- `work/PlanManagement/TimelyKitTrackingResult/README.md` +- `work/PlanManagement/TimelyKitTrackingResult/03-推进台账.md` +- `work/PlanManagement/TimelyKitTrackingResult/04-任务矩阵.md` +- `work/PlanManagement/TimelyKitTrackingResult/05-验收证据.md` +- `work/PlanManagement/TimelyKitTrackingResult/06-决策记录.md` +- `gptlog-process/gpdlog.md` + +### 验证结果 + +- 查询过程发布成功。 +- `@订单号=4222` 二级数据返回 `5960` 和 `7142`。 +- 同一生产订单号没有重复。 +- `5960` 显示 13 道工艺路线,`7142` 显示 4 道工艺路线。 + +### 下一步 + +- 登录页面展开 `4222`,确认二级数据同时显示所有匹配生产订单且不重复。 + +## 2026-06-30 11:47:54 复核同缺件物料多生产订单显示 + +### 复核内容 +- 按用户最新口径确认:同一个生产订单号不要出现重复,同一缺件物料所有匹配生产订单都显示。 + +### 验证结果 +- 执行 `EXEC dbo.[生产管理_及时齐套跟踪结果_查询] @订单号 = 4222`。 +- 二级数据中缺件物料 `22-103-060-YDZF-20V1.0-4.1` 当前同时返回生产订单 `5960` 和 `7142`。 +- 同一生产订单号未重复出现。 + +## 2026-06-30 生产订单关闭无工时可关闭处理 + +### 用户反馈 +- `dbo.计划排产_生产订单关闭_查询全部订单` 的“可关闭”查询以工时为基准。 +- 当前只能查出全部校验的工时再筛选。 +- 特殊情况:没有工时记录,但满足其他条件的订单也需要进入可关闭处理。 + +### 执行过程 +1. 读取线上过程定义,确认“可关闭”分支以 `dbo.View_生产工时视图` 为主表。 +2. 核对页面 `src/views/PlanManagement/PlannOrderClose/index.vue`,确认默认查询为“可关闭 + 机加”。 +3. 核对 `MES_接口_生产计划`、`View_生产工时视图` 字段,确认可从生产计划补充无工时订单。 +4. 查询样例,确认 `7410` 无工时,但计划数量、入库数量、终检合格数均为 `1`,单据状态为空,属性为机加件。 +5. 新增脚本 `db_backups/update_plan_order_close_no_work_hours_20260630.sql`。 +6. 将“可关闭”分支调整为有工时订单和无工时满足条件订单合并: + - 有工时订单继续要求全部工时校验。 + - 无工时订单免工时校验,但保留原可关闭条件。 +7. 初版全量查询超时后,改为先写入 `#工时订单` 临时表,再判断无工时,避免重复展开复杂视图。 +8. 发布存储过程成功。 +9. 验证 `@订单号=7410, @单据状态=可关闭, @属性=机加` 可返回。 +10. 验证默认“可关闭 + 机加”查询约 `0.56` 秒返回,并命中 `7280`、`7409`、`7410`。 + +### 修改文件 +- `db_backups/update_plan_order_close_no_work_hours_20260630.sql` +- `work/PlanManagement/PlannOrderClose/README.md` +- `work/PlanManagement/PlannOrderClose/01-项目功能内容.md` +- `work/PlanManagement/PlannOrderClose/02-项目程序开发详细步骤.md` +- `work/PlanManagement/PlannOrderClose/03-推进台账.md` +- `work/PlanManagement/PlannOrderClose/04-任务矩阵.md` +- `work/PlanManagement/PlannOrderClose/05-验收证据.md` +- `work/PlanManagement/PlannOrderClose/06-决策记录.md` +- `gptlog-process/gpdlog.md` + +### 验证结果 +- 数据库过程发布成功。 +- 无工时订单 `7410` 可进入可关闭结果。 +- 默认“可关闭 + 机加”查询未超时,约 `0.56` 秒返回。 + +## 2026-06-30 新增产品合格率(工位)页面 + +### 用户反馈 +- 查看 `doc/新增产品合格率.docx`。 +- 根据文档新增页面 `产品合格率(工位)`。 + +### 执行过程 +1. 解包并读取 `doc/新增产品合格率.docx`,确认页面放在生产管理下。 +2. 读取文档截图和文字,确认一级字段为关闭日期、生产订单号、物料名称、物料编码、计划数量、完成数量、不良数量、合格率。 +3. 确认二级字段为工序、工序号、工位、完工数量、不良数量、合格率、检验说明。 +4. 查询 `dbo.YL_质量检验_质检记录` 字段,确认生产订单号为 `计划号`,订单行号为 `行号`,工位字段为 `工位名称`。 +5. 查询 SAP 视图 `SBO_YL.dbo.UBT_OWOR`,确认关闭日期字段为 `实际结算日期`,已关闭口径为 `单据状态 IS NOT NULL`。 +6. 新增查询脚本 `db_backups/create_product_pass_rate_workstation_20260630.sql`。 +7. 初版四段名跨库查询较慢,改为 `OPENQUERY([SAP], ...)` 将 SAP 已关闭订单先取到本地临时表。 +8. 新增菜单脚本 `db_backups/add_product_pass_rate_workstation_menu_20260630.sql`,写入生产管理下 `产品合格率(工位)` 菜单。 +9. 新增前端页面 `src/views/ProductionManagement/ProductPassRateWorkstation/index.vue`,实现查询区、主表、展开二级明细和合格率颜色。 +10. 发布查询过程和菜单脚本。 +11. 验证样例 `@生产订单号=7649` 返回一级汇总和二级明细。 +12. 执行 `npm run build`,构建通过。 + +### 修改文件 +- `src/views/ProductionManagement/ProductPassRateWorkstation/index.vue` +- `db_backups/create_product_pass_rate_workstation_20260630.sql` +- `db_backups/add_product_pass_rate_workstation_menu_20260630.sql` +- `work/ProductionManagement/ProductPassRateWorkstation/README.md` +- `work/ProductionManagement/ProductPassRateWorkstation/01-项目功能内容.md` +- `work/ProductionManagement/ProductPassRateWorkstation/02-项目程序开发详细步骤.md` +- `work/ProductionManagement/ProductPassRateWorkstation/03-推进台账.md` +- `work/ProductionManagement/ProductPassRateWorkstation/04-任务矩阵.md` +- `work/ProductionManagement/ProductPassRateWorkstation/05-验收证据.md` +- `work/ProductionManagement/ProductPassRateWorkstation/06-决策记录.md` +- `gptlog-process/gpdlog.md` + +### 验证结果 +- 查询过程 `dbo.生产管理_产品合格率工位_查询` 发布成功,修改时间 `2026-06-30 14:31:00.690`。 +- 菜单写入 `12` 条角色记录,ID 范围 `236-247`。 +- 近 7 天查询返回 `175` 行,耗时约 `0.37` 秒。 +- 空条件查询自动限定近 30 天,返回 `1420` 行,耗时约 `1.17` 秒。 +- `npm run build` 通过,仅有项目既有 warning。 + +## 2026-06-30 产品合格率(工位)默认不查询和合格状态筛选 + +### 用户反馈 +- 默认进来不查询数据。 +- 增加合格和不合格筛选。 +- 主数据合格率小于 `100` 的为不合格。 +- 默认不合格。 + +### 执行过程 +1. 修改 `db_backups/create_product_pass_rate_workstation_20260630.sql`,新增 `@合格状态` 参数。 +2. 查询结果按主数据合格率过滤:`合格` 为大于等于 `100`,`不合格` 为小于 `100`,`全部` 不过滤。 +3. 修改 `src/views/ProductionManagement/ProductPassRateWorkstation/index.vue`,删除页面创建时自动查询。 +4. 查询区新增“合格状态”下拉,默认值为 `不合格`。 +5. 查询时向过程传入 `合格状态`。 +6. 发布查询过程成功。 +7. 验证近 30 天筛选结果:不合格 `50` 行,合格 `1370` 行,全部 `1420` 行。 +8. 执行 `npm run build`,构建通过。 + +### 修改文件 +- `src/views/ProductionManagement/ProductPassRateWorkstation/index.vue` +- `db_backups/create_product_pass_rate_workstation_20260630.sql` +- `work/ProductionManagement/ProductPassRateWorkstation/README.md` +- `work/ProductionManagement/ProductPassRateWorkstation/01-项目功能内容.md` +- `work/ProductionManagement/ProductPassRateWorkstation/02-项目程序开发详细步骤.md` +- `work/ProductionManagement/ProductPassRateWorkstation/03-推进台账.md` +- `work/ProductionManagement/ProductPassRateWorkstation/04-任务矩阵.md` +- `work/ProductionManagement/ProductPassRateWorkstation/05-验收证据.md` +- `work/ProductionManagement/ProductPassRateWorkstation/06-决策记录.md` +- `gptlog-process/gpdlog.md` + +### 验证结果 +- 页面进入不再自动查询。 +- 合格状态默认 `不合格`。 +- 不合格筛选最高合格率为 `99.99`,符合小于 `100` 的判定。 +- `npm run build` 通过,仅有项目既有 warning。 + +## 2026-06-30 产品合格率(工位)关闭日期拆分 + +### 用户反馈 +- 关闭日期筛选拆成两个筛选。 +- 客户不习惯一次选两个日期。 + +### 执行过程 +1. 修改 `src/views/ProductionManagement/ProductPassRateWorkstation/index.vue`。 +2. 将原 `daterange` 日期范围选择器拆成两个独立 `date` 日期选择器。 +3. 前端字段改为 `searchForm.closeDateStart` 和 `searchForm.closeDateEnd`。 +4. 查询参数仍然使用 `关闭日期_Start` 和 `关闭日期_End`,数据库过程无需修改。 +5. 执行 `npm run build`,构建通过。 +6. 更新产品合格率 README/01-05 文档和总日志。 + +### 修改文件 +- `src/views/ProductionManagement/ProductPassRateWorkstation/index.vue` +- `work/ProductionManagement/ProductPassRateWorkstation/01-项目功能内容.md` +- `work/ProductionManagement/ProductPassRateWorkstation/02-项目程序开发详细步骤.md` +- `work/ProductionManagement/ProductPassRateWorkstation/03-推进台账.md` +- `work/ProductionManagement/ProductPassRateWorkstation/04-任务矩阵.md` +- `work/ProductionManagement/ProductPassRateWorkstation/05-验收证据.md` +- `gptlog-process/gpdlog.md` + +### 验证结果 +- `npm run build` 通过,仅有项目既有 warning。 +- 数据库过程无需重新发布。 + +## 2026-06-30 产品合格率(工位)修正工序号来源 + +### 用户反馈 +- 工序号为什么都是空。 +- 工序号应取 `dbo.MES_接口_生产计划_生产任务.订单行号`。 +- 该表中订单行号肯定不会为空。 + +### 执行过程 +1. 查询 `dbo.MES_接口_生产计划_生产任务` 字段,确认存在 `AID`、`订单编号`、`订单行号`、`工序名称`、`指派对象`。 +2. 查询样例数据,确认 `订单行号` 在生产任务表中有值。 +3. 定位原脚本中工序号来源为 `COALESCE(View_生产订单_MES.订单行号, 质检记录.行号)`。 +4. 确认质检记录的 `TaskAID` 对应生产任务表的 `AID`。 +5. 修改 `db_backups/create_product_pass_rate_workstation_20260630.sql`: + - 明细关联表改为 `dbo.MES_接口_生产计划_生产任务`。 + - 关联条件改为 `q.TaskAID = t.AID`。 + - 工序号改为 `COALESCE(t.订单行号, q.行号)`。 + - 工序和工位补值也改为优先使用生产任务表的 `工序名称`、`指派对象`。 +6. 发布 `dbo.生产管理_产品合格率工位_查询` 成功。 +7. 验证 `7649` 二级明细工序号为 `1`、`2`、`3`。 +8. 验证近 30 天 `3281` 条二级明细中空工序号为 `0`。 + +### 修改文件 +- `db_backups/create_product_pass_rate_workstation_20260630.sql` +- `work/ProductionManagement/ProductPassRateWorkstation/01-项目功能内容.md` +- `work/ProductionManagement/ProductPassRateWorkstation/02-项目程序开发详细步骤.md` +- `work/ProductionManagement/ProductPassRateWorkstation/03-推进台账.md` +- `work/ProductionManagement/ProductPassRateWorkstation/04-任务矩阵.md` +- `work/ProductionManagement/ProductPassRateWorkstation/05-验收证据.md` +- `work/ProductionManagement/ProductPassRateWorkstation/06-决策记录.md` +- `gptlog-process/gpdlog.md` + +### 验证结果 +- 查询过程修改时间:`2026-06-30 15:12:24.840`。 +- `7649` 返回:领料 1、数车 2、打磨 3。 +- 近 30 天明细行数 `3281`,空工序号行数 `0`。 + +## 2026-06-30 AGV执行中任务改为已完成 + +### 用户反馈 +- 处理页面 `ProductionManagement/AGVtask/index` 里面任务状态为执行中的数据。 +- 所有执行中任务都改为已完成。 + +### 执行过程 +1. 读取页面 `src/views/ProductionManagement/AGVtask/index.vue`,确认页面中 `RUNNING` 显示为执行中,`FINISHED` 显示为已完成。 +2. 查询数据库对象,确认实时数据来自 `dbo.AGV_实时数据`,历史完成数据写入 `dbo.AGV_历史数据`。 +3. 处理前统计实时表状态:`PENDING 1`、`RUNNING 35`。 +4. 按完成任务口径处理 `RUNNING` 数据:插入历史表时 `TaskStatus` 写为 `FINISHED`,并设置 `EndTime`、`Duration`,随后从实时表删除这些执行中任务。 +5. 处理完成后,调用页面实时查询过程验证 `RUNNING` 无数据。 +6. 验证实时表仅剩 `PENDING 1`,最近 5 分钟历史表新增 `FINISHED 35`。 +7. 新增 AGVtask README 和 01-06 文档,记录功能内容、执行步骤、推进台账、任务矩阵、验收证据和决策记录。 + +### 修改文件 +- `work/ProductionManagement/AGVtask/README.md` +- `work/ProductionManagement/AGVtask/01-项目功能内容.md` +- `work/ProductionManagement/AGVtask/02-项目程序开发详细步骤.md` +- `work/ProductionManagement/AGVtask/03-推进台账.md` +- `work/ProductionManagement/AGVtask/04-任务矩阵.md` +- `work/ProductionManagement/AGVtask/05-验收证据.md` +- `work/ProductionManagement/AGVtask/06-决策记录.md` +- `gptlog-process/gpdlog.md` + +### 验证结果 +- 已转历史数量:`35`。 +- 页面实时查询过程按 `RUNNING` 查询返回空结果。 +- 实时表剩余状态:`PENDING 1`。 +- 历史表最近 5 分钟状态:`FINISHED 35`。 + +## 2026-06-30 设计报工任务模块方案文档修订 + +### 用户反馈 +- 读取 `doc/设计报工任务模块.docx`,梳理方案。 +- 项目号具体取哪个 SAP 视图字段后续提供。 +- 完成要求已有结束时间,未结束不能完成。 +- 删除任务时,如果已经有报工记录,不能删除。 +- 不参与之前任何生产/SAP/工时报表流程,整体独立。 +- 修改文档。 + +### 执行过程 +1. 解析 `doc/设计报工任务模块.docx` 正文,确认原始需求包含设计任务、设计报工、设计工时校验、设计工时报表四个页面。 +2. 对照参考页面: + - `ProcessManagement/PartDrawlook/index.vue` + - `PlanManagement/SelfMakePlando/index.vue` + - `ProductionManagement/WorkHoursCheck/index.vue` + - `ProductionManagement/Workhours/index.vue` +3. 新增 `work/ProductionManagement/DesignReportTask/` 文档目录。 +4. 写入 README 和 01-06 文档,记录功能内容、开发步骤、推进台账、任务矩阵、验收证据和决策记录。 +5. 将 Word 文档正文整理为确认版方案。 +6. 解析更新后的 Word 文档,验证关键口径已写入。 + +### 修改文件 +- `doc/设计报工任务模块.docx` +- `work/ProductionManagement/DesignReportTask/README.md` +- `work/ProductionManagement/DesignReportTask/01-项目功能内容.md` +- `work/ProductionManagement/DesignReportTask/02-项目程序开发详细步骤.md` +- `work/ProductionManagement/DesignReportTask/03-推进台账.md` +- `work/ProductionManagement/DesignReportTask/04-任务矩阵.md` +- `work/ProductionManagement/DesignReportTask/05-验收证据.md` +- `work/ProductionManagement/DesignReportTask/06-决策记录.md` +- `gptlog-process/gpdlog.md` + +### 验证结果 +- Word 文档已包含 `项目号:具体 SAP 视图和字段后续提供`。 +- Word 文档已包含 `未结束不能完成`。 +- Word 文档已包含 `已有设计报工记录不能删除`。 +- Word 文档已包含 `不上传 SAP` 和 `不参与现有生产工时报表`。 +- 任务矩阵中 `DRT-009 项目号来源` 状态为待确认,`DRT-010 数据库和页面开发` 状态为待开始。 diff --git a/src/views/PlanManagement/TimelyKitTrackingResult/index.vue b/src/views/PlanManagement/TimelyKitTrackingResult/index.vue index 86d7dfc..eb5d3b0 100644 --- a/src/views/PlanManagement/TimelyKitTrackingResult/index.vue +++ b/src/views/PlanManagement/TimelyKitTrackingResult/index.vue @@ -79,6 +79,7 @@ + @@ -93,7 +94,6 @@ - @@ -269,13 +269,13 @@ export default { 缺件物料编码: row.缺件物料编码, 缺件物料名称: row.缺件物料名称, 缺件数量: this.formatQuantity(row.缺件数量), + 库存数量: this.formatQuantity(row.库存数量), 缺件属性: row.缺件属性, 缺件生产订单号: row.缺件生产订单号, 进度: row.进度, 工艺路线: row.工艺路线, 工艺路线明细: this.parseRouteDetails(row.工艺路线明细), 预计完成时间: row.预计完成时间, - 采购员: row.采购员, 采购未清数量: this.formatQuantity(row.采购未清数量), 到货草稿: row.到货草稿, 质检状态: row.质检状态, @@ -315,39 +315,88 @@ export default { 辅助结束: 3, 开始加工: 4, 暂停: 5, - 报工: 6 + 报工: 6, + 装配加工: 4 } return statusMap[value] || 0 }, - isProcessComplete(process) { - const progress = this.toProcessNumber(process.进度) - const planCount = this.toProcessNumber(process.计划数量) - const finishCount = this.toProcessNumber(process.完成数量) - const checkedCount = this.toProcessNumber(process.收检合格数) + this.toProcessNumber(process.收检不合格数) - return progress >= 100 || - (planCount > 0 && finishCount >= planCount) || - (planCount > 0 && checkedCount >= planCount) + isOutsourceProcess(process) { + return process.指派对象 === '外协' || + String(process.工序名称 || '').includes('(外协)') || + String(process.工序名称 || '').includes('(外协)') }, - getProcessClass(process, index, processes) { - if (this.isProcessComplete(process)) { - return 'process-route-blue' - } + isBlueProcess(process) { const statusNum = this.getProcessStatusNum(process.加工状态) - if (this.isValidProcessDate(process.开工时间) || [2, 4].includes(statusNum) || this.toProcessNumber(process.进度) > 0) { + const countNum = parseInt(process.收检合格数) + return statusNum === 6 || statusNum === 3 || countNum > 0 + }, + isGreenProcess(process) { + return this.isOutsourceProcess(process) && + this.toProcessNumber(process.收料数量) > this.toProcessNumber(process.收检合格数) + this.toProcessNumber(process.收检不合格数) + }, + getProcessBaseClass(process) { + if (this.isGreenProcess(process)) { return 'process-route-green' } - if (index > 0 && this.isProcessComplete(processes[index - 1])) { - return 'process-route-orange' + + if (this.isBlueProcess(process)) { + return 'process-route-blue' } + + const statusNum = this.getProcessStatusNum(process.加工状态) + if (statusNum === 2 || statusNum === 4) { + return 'process-route-green' + } + return 'process-route-red' }, - getRouteProcessName(process) { - const name = String(process.工序名称 || '') - const assignee = String(process.指派对象 || '') - if (!assignee || name.includes(`(${assignee})`) || name.includes(`(${assignee})`)) { - return name + getOutsourceGroupClassState(processes) { + const classes = new Map() + let currentIndexes = [] + let lastProcess = null + + const flushOutsourceRun = () => { + if (currentIndexes.length > 0 && lastProcess) { + const className = this.getProcessBaseClass(lastProcess) + currentIndexes.forEach(index => classes.set(index, className)) + } + currentIndexes = [] + lastProcess = null } - return `${name}(${assignee})` + + const isSameContinuousGroup = process => { + if (!lastProcess) { + return true + } + const lineNo = this.toProcessNumber(process.订单行号) + const lastLineNo = this.toProcessNumber(lastProcess.订单行号) + return lineNo === lastLineNo + 1 && + String(process.外协分组 || '') === String(lastProcess.外协分组 || '') + } + + processes.forEach((process, index) => { + if (!this.isOutsourceProcess(process)) { + flushOutsourceRun() + return + } + if (!isSameContinuousGroup(process)) { + flushOutsourceRun() + } + currentIndexes.push(index) + lastProcess = process + }) + flushOutsourceRun() + + return classes + }, + getProcessClass(process, index, outsourceGroupClasses) { + if (this.isOutsourceProcess(process)) { + return outsourceGroupClasses.get(index) || this.getProcessBaseClass(process) + } + return this.getProcessBaseClass(process) + }, + getRouteProcessName(process) { + return String(process.工序名称 || '') }, escapeProcessHtml(value) { return String(value == null ? '' : value) @@ -365,6 +414,7 @@ export default { const maxPerRow = 8 const rows = Math.ceil(processes.length / maxPerRow) + const outsourceGroupClasses = this.getOutsourceGroupClassState(processes) let html = '
' for (let rowIndex = 0; rowIndex < rows; rowIndex++) { @@ -376,20 +426,20 @@ export default { html += '' rowProcesses.forEach((process, index) => { - const className = this.getProcessClass(process, startIndex + index, processes) + const className = this.getProcessClass(process, startIndex + index, outsourceGroupClasses) const date = this.formatDate(process.计划开始时间 || process.计划完成时间) html += `` if (index < rowProcesses.length - 1) html += '' }) html += '' rowProcesses.forEach((process, index) => { - const className = this.getProcessClass(process, startIndex + index, processes) + const className = this.getProcessClass(process, startIndex + index, outsourceGroupClasses) html += `` if (index < rowProcesses.length - 1) html += '' }) html += '' rowProcesses.forEach((process, index) => { - const className = this.getProcessClass(process, startIndex + index, processes) + const className = this.getProcessClass(process, startIndex + index, outsourceGroupClasses) const count = this.formatQuantity(process.收检合格数) html += `` if (index < rowProcesses.length - 1) html += '' @@ -473,39 +523,53 @@ export default { .process-route { overflow-x: auto; - padding: 2px 0; + padding: 0; + text-align: left; } ::v-deep .process-route-wrap { min-width: 480px; + text-align: left; } ::v-deep .process-route-table { - border-collapse: separate; - border-spacing: 0; - margin: 0 auto; + border-collapse: collapse; + margin: 0; + text-align: left; + table-layout: auto; } ::v-deep .process-route-table td { - border-radius: 2px; - line-height: 20px; - min-width: 72px; - padding: 2px 5px; - text-align: center; + line-height: 1.4; + min-width: 35px; + padding: 2px 2px; + text-align: left; white-space: nowrap; } -::v-deep .process-route-date, +::v-deep .process-route-date { + color: #8899aa !important; + font-size: 10px !important; + padding: 2px 2px !important; +} + ::v-deep .process-route-count { - font-size: 12px; + font-size: 12px !important; + font-weight: 700; } ::v-deep .process-route-arrow, ::v-deep .process-route-arrow-hidden { background: transparent; - color: #606266; - min-width: 18px; - width: 18px; + min-width: 8px; + padding: 2px 0 !important; + width: 8px; +} + +::v-deep .process-route-arrow { + color: rgba(0, 164, 255, 0.6) !important; + font-size: 10px !important; + text-align: center !important; } ::v-deep .process-route-arrow-hidden { @@ -513,29 +577,24 @@ export default { } ::v-deep .process-route-spacer td { - height: 6px; - line-height: 6px; - padding: 0; + height: 4px; + line-height: 1 !important; + padding: 0 !important; } ::v-deep .process-route-green { - background: #f0f9eb; - color: #67c23a; + color: #28d961; + font-weight: 700; } ::v-deep .process-route-blue { - background: #ecf5ff; - color: #409eff; -} - -::v-deep .process-route-orange { - background: #fdf6ec; - color: #e6a23c; + color: #09a8ff; + font-weight: 700; } ::v-deep .process-route-red { - background: #fef0f0; - color: #f56c6c; + color: #ff3f37; + font-weight: 700; } ::v-deep .detail-row td { diff --git a/src/views/ProductionManagement/ProductPassRateWorkstation/index.vue b/src/views/ProductionManagement/ProductPassRateWorkstation/index.vue new file mode 100644 index 0000000..32c9081 --- /dev/null +++ b/src/views/ProductionManagement/ProductPassRateWorkstation/index.vue @@ -0,0 +1,283 @@ + + + + + diff --git a/src/views/QualityManagement/CheckTask/processReceive.vue b/src/views/QualityManagement/CheckTask/processReceive.vue index 44f7298..0a358ae 100644 --- a/src/views/QualityManagement/CheckTask/processReceive.vue +++ b/src/views/QualityManagement/CheckTask/processReceive.vue @@ -221,18 +221,7 @@ width="80" prop="工位名称" /> - - + + +
${this.escapeProcessHtml(date)}
${this.escapeProcessHtml(this.getRouteProcessName(process))}
合格${this.escapeProcessHtml(count)}