From a6a92ffeb26d7c58e5c90064c43a23c9c296489e Mon Sep 17 00:00:00 2001 From: zhangxinyang Date: Fri, 10 Jul 2026 15:19:26 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E4=B8=8A=E4=BC=A0=E5=BD=93=E5=89=8D?= =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E5=8C=BA=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 10 + ..._design_report_category_field_20260709.sql | 413 ++++++++ ...ign_report_task_menu_account1_20260709.sql | 128 +++ ...ate_design_report_task_module_20260630.sql | 224 +++- .../MES_设计报工_任务.json | 48 + .../MES_设计报工_校验记录.json | 14 + .../MES_设计报工_记录.json | 34 + .../_summary.json | 17 + ..._design_report_complete_guard_20260709.sql | 242 +++++ ...ix_design_report_delete_guard_20260709.sql | 76 ++ ...sign_report_multi_person_work_20260709.sql | 267 +++++ ..._design_report_project_source_20260709.sql | 29 + doc/设计报工任务模块.docx | Bin 42889 -> 12393 bytes gptlog-process/gpdlog.md | 973 ++++++++++++++++++ .../PlanManagement/SelfMakePlando/index.vue | 16 +- .../DesignReportTask/Check/index.vue | 112 +- .../DesignReportTask/HoursReport/index.vue | 82 +- .../DesignReportTask/Report/index.vue | 220 +++- .../DesignReportTask/Task/index.vue | 144 ++- .../DeviceInformation/01-项目功能内容.md | 61 -- .../02-项目程序开发详细步骤.md | 58 -- .../DeviceInformation/03-推进台账.md | 185 ---- .../DeviceInformation/04-任务矩阵.md | 25 - .../DeviceInformation/05-验收证据.md | 288 ------ .../DeviceInformation/06-决策记录.md | 49 - .../DeviceInformation/README.md | 18 - .../DeviceInformation/修改设备信息维护.docx | Bin 18500 -> 0 bytes .../DeviceInformation/设备信息.xlsx | Bin 18573 -> 0 bytes .../DesignReportTask/01-项目功能内容.md | 2 +- .../02-项目程序开发详细步骤.md | 3 +- .../DesignReportTask/03-推进台账.md | 29 + .../DesignReportTask/04-任务矩阵.md | 3 +- .../DesignReportTask/05-验收证据.md | 17 +- .../DesignReportTask/06-决策记录.md | 20 +- .../DesignReportTask/README.md | 2 +- 35 files changed, 3031 insertions(+), 778 deletions(-) create mode 100644 AGENTS.md create mode 100644 db_backups/add_design_report_category_field_20260709.sql create mode 100644 db_backups/add_design_report_task_menu_account1_20260709.sql create mode 100644 db_backups/design_report_data_backup_20260709_110417/MES_设计报工_任务.json create mode 100644 db_backups/design_report_data_backup_20260709_110417/MES_设计报工_校验记录.json create mode 100644 db_backups/design_report_data_backup_20260709_110417/MES_设计报工_记录.json create mode 100644 db_backups/design_report_data_backup_20260709_110417/_summary.json create mode 100644 db_backups/fix_design_report_complete_guard_20260709.sql create mode 100644 db_backups/fix_design_report_delete_guard_20260709.sql create mode 100644 db_backups/update_design_report_multi_person_work_20260709.sql create mode 100644 db_backups/update_design_report_project_source_20260709.sql delete mode 100644 work/DeviceManagement/DeviceInformation/01-项目功能内容.md delete mode 100644 work/DeviceManagement/DeviceInformation/02-项目程序开发详细步骤.md delete mode 100644 work/DeviceManagement/DeviceInformation/03-推进台账.md delete mode 100644 work/DeviceManagement/DeviceInformation/04-任务矩阵.md delete mode 100644 work/DeviceManagement/DeviceInformation/05-验收证据.md delete mode 100644 work/DeviceManagement/DeviceInformation/06-决策记录.md delete mode 100644 work/DeviceManagement/DeviceInformation/README.md delete mode 100644 work/DeviceManagement/DeviceInformation/修改设备信息维护.docx delete mode 100644 work/DeviceManagement/DeviceInformation/设备信息.xlsx diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..1d7b01e --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,10 @@ +# AGENTS.md + +## Scope + +日志记录规则 +每次 GPT/Codex 执行完毕后,须将完整的执行过程日志追加至: + +gptlog-process/gpdlog.md + +日志包含提问和结论以及完整的执行过程,写入该文件的日志内容必须使用中文记录。 diff --git a/db_backups/add_design_report_category_field_20260709.sql b/db_backups/add_design_report_category_field_20260709.sql new file mode 100644 index 0000000..9d4ebd9 --- /dev/null +++ b/db_backups/add_design_report_category_field_20260709.sql @@ -0,0 +1,413 @@ +USE [YL_MESDB]; +GO + +IF COL_LENGTH(N'[dbo].[MES_设计报工_任务]', N'类别') IS NULL +BEGIN + ALTER TABLE [dbo].[MES_设计报工_任务] ADD [类别] nvarchar(100) NULL; +END +GO + +CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_查询] + @DID int = NULL, + @项目号 nvarchar(100) = N'', + @物料编码 nvarchar(100) = N'', + @图号 nvarchar(100) = N'', + @类别 nvarchar(100) = N'', + @关联父件物料编码 nvarchar(100) = N'', + @预计开始时间_Start nvarchar(30) = N'', + @预计开始时间_End nvarchar(30) = N'', + @预计结束时间_Start nvarchar(30) = N'', + @预计结束时间_End nvarchar(30) = N'', + @单据状态 nvarchar(50) = N'', + @当前操作人ID nvarchar(100) = N'', + @当前操作人 nvarchar(100) = N'' +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @预计开始日期1 datetime = TRY_CONVERT(datetime, NULLIF(@预计开始时间_Start, N'')); + DECLARE @预计开始日期2 datetime = TRY_CONVERT(datetime, NULLIF(@预计开始时间_End, N'')); + DECLARE @预计结束日期1 datetime = TRY_CONVERT(datetime, NULLIF(@预计结束时间_Start, N'')); + DECLARE @预计结束日期2 datetime = TRY_CONVERT(datetime, NULLIF(@预计结束时间_End, N'')); + + SELECT TOP 1000 + t.[DID], + t.[项目号], + t.[物料编码], + t.[物料名称], + t.[图号], + t.[类别], + t.[任务描述], + t.[关联父件物料编码], + t.[关联父件物料名称], + t.[设计要求], + t.[研发立项号], + t.[研发目的], + t.[指派对象ID], + t.[指派对象], + CONVERT(varchar(19), t.[预计开始时间], 120) AS [预计开始时间], + CONVERT(varchar(19), t.[预计结束时间], 120) AS [预计结束时间], + t.[单据状态], + CONVERT(varchar(19), t.[创建日期], 120) AS [创建日期], + t.[创建人], + t.[最后编辑人], + CONVERT(varchar(19), t.[最后编辑时间], 120) AS [最后编辑时间], + t.[备注], + ISNULL(r.[报工次数], 0) AS [报工次数], + ISNULL(r.[未结束报工数], 0) AS [未结束报工数], + ISNULL(r.[当前用户未结束报工数], 0) AS [当前用户未结束报工数], + ISNULL(p.[未结束报工人员], N'') AS [未结束报工人员], + CONVERT(varchar(19), r.[最后开始时间], 120) AS [最后开始时间], + CONVERT(varchar(19), r.[最后结束时间], 120) AS [最后结束时间] + FROM [dbo].[MES_设计报工_任务] AS t + OUTER APPLY + ( + SELECT + COUNT(1) AS [报工次数], + SUM(CASE WHEN rr.[结束时间] IS NULL THEN 1 ELSE 0 END) AS [未结束报工数], + SUM(CASE + WHEN rr.[结束时间] IS NULL + AND ( + (NULLIF(@当前操作人ID, N'') IS NOT NULL AND ISNULL(rr.[操作人ID], N'') = @当前操作人ID) + OR (NULLIF(@当前操作人ID, N'') IS NULL AND NULLIF(@当前操作人, N'') IS NOT NULL AND ISNULL(rr.[操作人], N'') = @当前操作人) + ) + THEN 1 ELSE 0 END) AS [当前用户未结束报工数], + MAX(rr.[开始时间]) AS [最后开始时间], + MAX(rr.[结束时间]) AS [最后结束时间] + FROM [dbo].[MES_设计报工_记录] AS rr + WHERE rr.[DID] = t.[DID] + ) AS r + OUTER APPLY + ( + SELECT STRING_AGG(CONVERT(nvarchar(max), x.[操作人标识]), N'、') AS [未结束报工人员] + FROM + ( + SELECT DISTINCT COALESCE(NULLIF(rr2.[操作人], N''), NULLIF(rr2.[操作人ID], N''), N'未填写操作人') AS [操作人标识] + FROM [dbo].[MES_设计报工_记录] AS rr2 + WHERE rr2.[DID] = t.[DID] + AND rr2.[结束时间] IS NULL + ) AS x + ) AS p + WHERE + (@DID IS NULL OR @DID = 0 OR t.[DID] = @DID) + AND (ISNULL(@项目号, N'') = N'' OR t.[项目号] LIKE N'%' + @项目号 + N'%') + AND (ISNULL(@物料编码, N'') = N'' OR t.[物料编码] LIKE N'%' + @物料编码 + N'%') + AND (ISNULL(@图号, N'') = N'' OR t.[图号] LIKE N'%' + @图号 + N'%') + AND (ISNULL(@类别, N'') = N'' OR t.[类别] LIKE N'%' + @类别 + N'%') + AND (ISNULL(@关联父件物料编码, N'') = N'' OR t.[关联父件物料编码] LIKE N'%' + @关联父件物料编码 + N'%') + AND (ISNULL(@单据状态, N'') = N'' OR @单据状态 = N'全部' OR t.[单据状态] = @单据状态) + AND (@预计开始日期1 IS NULL OR t.[预计开始时间] >= @预计开始日期1) + AND (@预计开始日期2 IS NULL OR t.[预计开始时间] < DATEADD(day, 1, @预计开始日期2)) + AND (@预计结束日期1 IS NULL OR t.[预计结束时间] >= @预计结束日期1) + AND (@预计结束日期2 IS NULL OR t.[预计结束时间] < DATEADD(day, 1, @预计结束日期2)) + ORDER BY t.[DID] DESC; +END +GO + +CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_新增] + @项目号 nvarchar(100) = N'', + @物料编码 nvarchar(100) = N'', + @物料名称 nvarchar(200) = N'', + @图号 nvarchar(100) = N'', + @类别 nvarchar(100) = N'', + @任务描述 nvarchar(500) = N'', + @关联父件物料编码 nvarchar(100) = N'', + @关联父件物料名称 nvarchar(200) = N'', + @设计要求 nvarchar(max) = N'', + @研发立项号 nvarchar(100) = N'', + @研发目的 nvarchar(500) = N'', + @指派对象ID nvarchar(1000) = N'', + @指派对象 nvarchar(1000) = N'', + @预计开始时间 nvarchar(30) = N'', + @预计结束时间 nvarchar(30) = N'', + @创建人 nvarchar(100) = N'', + @备注 nvarchar(500) = N'' +AS +BEGIN + SET NOCOUNT ON; + + INSERT INTO [dbo].[MES_设计报工_任务] + ( + [项目号], [物料编码], [物料名称], [图号], [类别], [任务描述], + [关联父件物料编码], [关联父件物料名称], [设计要求], + [研发立项号], [研发目的], [指派对象ID], [指派对象], + [预计开始时间], [预计结束时间], [单据状态], + [创建人], [最后编辑人], [最后编辑时间], [备注] + ) + VALUES + ( + NULLIF(@项目号, N''), NULLIF(@物料编码, N''), NULLIF(@物料名称, N''), NULLIF(@图号, N''), NULLIF(@类别, N''), NULLIF(@任务描述, N''), + NULLIF(@关联父件物料编码, N''), NULLIF(@关联父件物料名称, N''), NULLIF(@设计要求, N''), + NULLIF(@研发立项号, N''), NULLIF(@研发目的, N''), NULLIF(@指派对象ID, N''), NULLIF(@指派对象, N''), + TRY_CONVERT(datetime, NULLIF(@预计开始时间, N'')), TRY_CONVERT(datetime, NULLIF(@预计结束时间, N'')), N'待开始', + NULLIF(@创建人, N''), NULLIF(@创建人, N''), GETDATE(), NULLIF(@备注, N'') + ); + + SELECT CAST(1 AS int) AS [result], N'新增成功' AS [message], SCOPE_IDENTITY() AS [DID]; +END +GO + +CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_编辑] + @DID int, + @项目号 nvarchar(100) = N'', + @物料编码 nvarchar(100) = N'', + @物料名称 nvarchar(200) = N'', + @图号 nvarchar(100) = N'', + @类别 nvarchar(100) = N'', + @任务描述 nvarchar(500) = N'', + @关联父件物料编码 nvarchar(100) = N'', + @关联父件物料名称 nvarchar(200) = N'', + @设计要求 nvarchar(max) = N'', + @研发立项号 nvarchar(100) = N'', + @研发目的 nvarchar(500) = N'', + @指派对象ID nvarchar(1000) = N'', + @指派对象 nvarchar(1000) = N'', + @预计开始时间 nvarchar(30) = N'', + @预计结束时间 nvarchar(30) = N'', + @最后编辑人 nvarchar(100) = N'', + @备注 nvarchar(500) = N'' +AS +BEGIN + SET NOCOUNT ON; + + IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID) + BEGIN + SELECT CAST(0 AS int) AS [result], N'任务不存在' AS [message]; + RETURN; + END + + UPDATE [dbo].[MES_设计报工_任务] + SET + [项目号] = NULLIF(@项目号, N''), + [物料编码] = NULLIF(@物料编码, N''), + [物料名称] = NULLIF(@物料名称, N''), + [图号] = NULLIF(@图号, N''), + [类别] = NULLIF(@类别, N''), + [任务描述] = NULLIF(@任务描述, N''), + [关联父件物料编码] = NULLIF(@关联父件物料编码, N''), + [关联父件物料名称] = NULLIF(@关联父件物料名称, N''), + [设计要求] = NULLIF(@设计要求, N''), + [研发立项号] = NULLIF(@研发立项号, N''), + [研发目的] = NULLIF(@研发目的, N''), + [指派对象ID] = NULLIF(@指派对象ID, N''), + [指派对象] = NULLIF(@指派对象, N''), + [预计开始时间] = TRY_CONVERT(datetime, NULLIF(@预计开始时间, N'')), + [预计结束时间] = TRY_CONVERT(datetime, NULLIF(@预计结束时间, N'')), + [最后编辑人] = NULLIF(@最后编辑人, N''), + [最后编辑时间] = GETDATE(), + [备注] = NULLIF(@备注, N'') + WHERE [DID] = @DID; + + SELECT CAST(1 AS int) AS [result], N'编辑成功' AS [message]; +END +GO + +CREATE OR ALTER PROCEDURE [dbo].[设计报工_记录_查询] + @DID int = NULL, + @项目号 nvarchar(100) = N'', + @物料编码 nvarchar(100) = N'', + @类别 nvarchar(100) = N'', + @操作人 nvarchar(100) = N'', + @开始日期 nvarchar(30) = N'', + @结束日期 nvarchar(30) = N'', + @校验状态 nvarchar(50) = N'' +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @开始 datetime = TRY_CONVERT(datetime, NULLIF(@开始日期, N'')); + DECLARE @结束 datetime = TRY_CONVERT(datetime, NULLIF(@结束日期, N'')); + + SELECT TOP 1000 + r.[RID], + r.[DID], + t.[项目号], + t.[物料编码], + t.[物料名称], + t.[图号], + t.[类别], + t.[任务描述], + t.[指派对象], + r.[操作人ID], + r.[操作人], + CONVERT(varchar(19), r.[开始时间], 120) AS [开始时间], + CONVERT(varchar(19), r.[结束时间], 120) AS [结束时间], + r.[工时秒数], + CAST(CAST(ISNULL(r.[工时秒数], 0) / 3600.0 AS decimal(18, 2)) AS varchar(30)) AS [工时小时], + r.[报工状态], + r.[已校验], + CASE WHEN r.[已校验] = 1 THEN N'已校验' ELSE N'未校验' END AS [校验状态], + r.[校验人], + CONVERT(varchar(19), r.[校验时间], 120) AS [校验时间], + r.[备注], + t.[单据状态] + FROM [dbo].[MES_设计报工_记录] AS r + INNER JOIN [dbo].[MES_设计报工_任务] AS t ON r.[DID] = t.[DID] + WHERE + (@DID IS NULL OR @DID = 0 OR r.[DID] = @DID) + AND (ISNULL(@项目号, N'') = N'' OR t.[项目号] LIKE N'%' + @项目号 + N'%') + AND (ISNULL(@物料编码, N'') = N'' OR t.[物料编码] LIKE N'%' + @物料编码 + N'%') + AND (ISNULL(@类别, N'') = N'' OR t.[类别] LIKE N'%' + @类别 + N'%') + AND (ISNULL(@操作人, N'') = N'' OR r.[操作人] LIKE N'%' + @操作人 + N'%') + AND (@开始 IS NULL OR r.[开始时间] >= @开始) + AND (@结束 IS NULL OR r.[开始时间] < DATEADD(day, 1, @结束)) + AND ( + ISNULL(@校验状态, N'') = N'' + OR @校验状态 = N'全部' + OR (@校验状态 = N'已校验' AND r.[已校验] = 1) + OR (@校验状态 = N'未校验' AND r.[已校验] = 0) + ) + ORDER BY r.[RID] DESC; +END +GO + +CREATE OR ALTER PROCEDURE [dbo].[设计报工_工时校验_查询] + @DID int = NULL, + @项目号 nvarchar(100) = N'', + @物料编码 nvarchar(100) = N'', + @类别 nvarchar(100) = N'', + @操作人 nvarchar(100) = N'', + @开始日期 nvarchar(30) = N'', + @结束日期 nvarchar(30) = N'', + @校验状态 nvarchar(50) = N'未校验' +AS +BEGIN + SET NOCOUNT ON; + + EXEC [dbo].[设计报工_记录_查询] + @DID = @DID, + @项目号 = @项目号, + @物料编码 = @物料编码, + @类别 = @类别, + @操作人 = @操作人, + @开始日期 = @开始日期, + @结束日期 = @结束日期, + @校验状态 = @校验状态; +END +GO + +CREATE OR ALTER PROCEDURE [dbo].[设计报工_工时报表_作业者工时_查询] + @开始日期 nvarchar(30) = N'', + @结束日期 nvarchar(30) = N'', + @操作人 nvarchar(100) = N'', + @项目号 nvarchar(100) = N'', + @物料编码 nvarchar(100) = N'', + @类别 nvarchar(100) = N'', + @DID int = NULL +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @开始 datetime = TRY_CONVERT(datetime, NULLIF(@开始日期, N'')); + DECLARE @结束 datetime = TRY_CONVERT(datetime, NULLIF(@结束日期, N'')); + + ;WITH base AS + ( + SELECT + r.[RID], + r.[DID], + ISNULL(r.[操作人], N'') AS [操作人], + CONVERT(varchar(10), r.[开始时间], 120) AS [工作日期], + t.[项目号], + t.[物料编码], + t.[物料名称], + t.[图号], + t.[类别], + t.[任务描述], + r.[开始时间], + r.[结束时间], + ISNULL(r.[工时秒数], 0) AS [工时秒数], + r.[已校验], + r.[备注] + FROM [dbo].[MES_设计报工_记录] AS r + INNER JOIN [dbo].[MES_设计报工_任务] AS t ON r.[DID] = t.[DID] + WHERE + r.[开始时间] IS NOT NULL + AND r.[结束时间] IS NOT NULL + AND (@开始 IS NULL OR r.[开始时间] >= @开始) + AND (@结束 IS NULL OR r.[开始时间] < DATEADD(day, 1, @结束)) + AND (ISNULL(@操作人, N'') = N'' OR r.[操作人] LIKE N'%' + @操作人 + N'%') + AND (ISNULL(@项目号, N'') = N'' OR t.[项目号] LIKE N'%' + @项目号 + N'%') + AND (ISNULL(@物料编码, N'') = N'' OR t.[物料编码] LIKE N'%' + @物料编码 + N'%') + AND (ISNULL(@类别, N'') = N'' OR t.[类别] LIKE N'%' + @类别 + N'%') + AND (@DID IS NULL OR @DID = 0 OR r.[DID] = @DID) + ), + result AS + ( + SELECT + 1 AS [Level], + N'p-' + [操作人] AS [id], + CAST(N'' AS nvarchar(100)) AS [parentId], + [操作人], + CAST(N'' AS nvarchar(20)) AS [工作日期], + CAST(NULL AS int) AS [RID], + CAST(NULL AS int) AS [DID], + CAST(N'' AS nvarchar(100)) AS [项目号], + CAST(N'' AS nvarchar(100)) AS [物料编码], + CAST(N'' AS nvarchar(200)) AS [物料名称], + CAST(N'' AS nvarchar(100)) AS [图号], + CAST(N'' AS nvarchar(100)) AS [类别], + CAST(N'' AS nvarchar(500)) AS [任务描述], + CAST(N'' AS varchar(19)) AS [开始时间], + CAST(N'' AS varchar(19)) AS [结束时间], + COUNT(1) AS [报工次数], + CAST(SUM([工时秒数]) / 3600.0 AS decimal(18, 2)) AS [工时小时], + CAST(N'' AS nvarchar(20)) AS [校验状态], + CAST(N'' AS nvarchar(500)) AS [备注] + FROM base + GROUP BY [操作人] + + UNION ALL + + SELECT + 2 AS [Level], + N'd-' + [操作人] + N'-' + [工作日期] AS [id], + N'p-' + [操作人] AS [parentId], + [操作人], + [工作日期], + CAST(NULL AS int) AS [RID], + CAST(NULL AS int) AS [DID], + CAST(N'' AS nvarchar(100)) AS [项目号], + CAST(N'' AS nvarchar(100)) AS [物料编码], + CAST(N'' AS nvarchar(200)) AS [物料名称], + CAST(N'' AS nvarchar(100)) AS [图号], + CAST(N'' AS nvarchar(100)) AS [类别], + CAST(N'' AS nvarchar(500)) AS [任务描述], + CAST(N'' AS varchar(19)) AS [开始时间], + CAST(N'' AS varchar(19)) AS [结束时间], + COUNT(1) AS [报工次数], + CAST(SUM([工时秒数]) / 3600.0 AS decimal(18, 2)) AS [工时小时], + CAST(N'' AS nvarchar(20)) AS [校验状态], + CAST(N'' AS nvarchar(500)) AS [备注] + FROM base + GROUP BY [操作人], [工作日期] + + UNION ALL + + SELECT + 3 AS [Level], + N'r-' + CAST([RID] AS nvarchar(20)) AS [id], + N'd-' + [操作人] + N'-' + [工作日期] AS [parentId], + [操作人], + [工作日期], + [RID], + [DID], + ISNULL([项目号], N'') AS [项目号], + ISNULL([物料编码], N'') AS [物料编码], + ISNULL([物料名称], N'') AS [物料名称], + ISNULL([图号], N'') AS [图号], + ISNULL([类别], N'') AS [类别], + ISNULL([任务描述], N'') AS [任务描述], + CONVERT(varchar(19), [开始时间], 120) AS [开始时间], + CONVERT(varchar(19), [结束时间], 120) AS [结束时间], + 1 AS [报工次数], + CAST([工时秒数] / 3600.0 AS decimal(18, 2)) AS [工时小时], + CASE WHEN [已校验] = 1 THEN N'已校验' ELSE N'未校验' END AS [校验状态], + ISNULL([备注], N'') AS [备注] + FROM base + ) + SELECT * + FROM result + ORDER BY [操作人], [工作日期], [Level], [RID]; +END +GO diff --git a/db_backups/add_design_report_task_menu_account1_20260709.sql b/db_backups/add_design_report_task_menu_account1_20260709.sql new file mode 100644 index 0000000..0ba9b58 --- /dev/null +++ b/db_backups/add_design_report_task_menu_account1_20260709.sql @@ -0,0 +1,128 @@ +USE [YL_MESDB] +GO + +SET NOCOUNT ON; + +DECLARE @TargetAccount int = 1; +DECLARE @ParentTitle varchar(100) = '生产管理'; +DECLARE @ParentId int; + +SELECT TOP (1) + @ParentId = [id] +FROM [dbo].[登录基础数据_二级菜单] +WHERE [账号代码] = @TargetAccount + AND [是否启用] = 1 + AND [pid] = 0 + AND [title] = @ParentTitle +ORDER BY [id]; + +IF @ParentId IS NULL +BEGIN + RAISERROR('未找到账号 1 的生产管理父菜单。', 16, 1); + RETURN; +END; + +DECLARE @Menus TABLE +( + rn int IDENTITY(1,1) PRIMARY KEY, + [path] varchar(300) NOT NULL, + [componet] varchar(300) NOT NULL, + [name] varchar(100) NOT NULL, + [title] varchar(100) NOT NULL, + [icon] varchar(100) NULL +); + +INSERT INTO @Menus ([path], [componet], [name], [title], [icon]) +VALUES + ('DesignReportTask/Task/index', '/ProductionManagement/DesignReportTask/Task/index', 'DesignReportTask', '设计任务', 'DocumentImport'), + ('DesignReportTask/Report/index', '/ProductionManagement/DesignReportTask/Report/index', 'DesignReportWork', '设计报工', 'DocumentImport'), + ('DesignReportTask/Check/index', '/ProductionManagement/DesignReportTask/Check/index', 'DesignReportCheck', '设计工时校验', 'PayStateSearch'), + ('DesignReportTask/HoursReport/index', '/ProductionManagement/DesignReportTask/HoursReport/index', 'DesignReportHoursReport', '设计工时报表', 'DimensionsSummaryReport'); + +DECLARE @BaseId int; + +SELECT @BaseId = ISNULL(MAX([id]), 0) +FROM [dbo].[登录基础数据_二级菜单]; + +;WITH MissingMenus AS +( + SELECT + ROW_NUMBER() OVER (ORDER BY m.rn) AS new_rn, + m.[path], + m.[componet], + m.[name], + m.[title], + m.[icon] + FROM @Menus AS m + WHERE NOT EXISTS + ( + SELECT 1 + FROM [dbo].[登录基础数据_二级菜单] AS existing + WHERE existing.[账号代码] = @TargetAccount + AND + ( + existing.[path] = m.[path] + OR existing.[componet] = m.[componet] + OR existing.[title] = m.[title] + ) + ) +) +INSERT INTO [dbo].[登录基础数据_二级菜单] + ([id], [pid], [path], [componet], [redirect], [name], [title], [icon], [账号代码], [模块代码], [是否启用], [操作时间]) +SELECT + @BaseId + new_rn, + @ParentId, + [path], + [componet], + NULL, + [name], + [title], + [icon], + @TargetAccount, + @BaseId + new_rn, + 1, + GETDATE() +FROM MissingMenus; + +UPDATE target +SET + target.[pid] = @ParentId, + target.[path] = source.[path], + target.[componet] = source.[componet], + target.[name] = source.[name], + target.[title] = source.[title], + target.[icon] = source.[icon], + target.[模块代码] = target.[id], + target.[是否启用] = 1, + target.[操作时间] = GETDATE() +FROM [dbo].[登录基础数据_二级菜单] AS target +INNER JOIN @Menus AS source + ON target.[账号代码] = @TargetAccount + AND + ( + target.[path] = source.[path] + OR target.[componet] = source.[componet] + OR target.[title] = source.[title] + ); + +SELECT + [id], + [pid], + [path], + [componet], + [name], + [title], + [icon], + [账号代码], + [模块代码], + [是否启用] +FROM [dbo].[登录基础数据_二级菜单] +WHERE [账号代码] = @TargetAccount + AND + ( + [path] IN (SELECT [path] FROM @Menus) + OR [componet] IN (SELECT [componet] FROM @Menus) + OR [title] IN (SELECT [title] FROM @Menus) + ) +ORDER BY [id]; +GO diff --git a/db_backups/create_design_report_task_module_20260630.sql b/db_backups/create_design_report_task_module_20260630.sql index 9ee75c8..b2a7be0 100644 --- a/db_backups/create_design_report_task_module_20260630.sql +++ b/db_backups/create_design_report_task_module_20260630.sql @@ -21,6 +21,7 @@ BEGIN [物料编码] nvarchar(100) NULL, [物料名称] nvarchar(200) NULL, [图号] nvarchar(100) NULL, + [类别] nvarchar(100) NULL, [任务描述] nvarchar(500) NULL, [关联父件物料编码] nvarchar(100) NULL, [关联父件物料名称] nvarchar(200) NULL, @@ -41,6 +42,12 @@ BEGIN END GO +IF COL_LENGTH(N'[dbo].[MES_设计报工_任务]', N'类别') IS NULL +BEGIN + ALTER TABLE [dbo].[MES_设计报工_任务] ADD [类别] nvarchar(100) NULL; +END +GO + IF OBJECT_ID(N'[dbo].[MES_设计报工_记录]', N'U') IS NULL BEGIN CREATE TABLE [dbo].[MES_设计报工_记录] @@ -157,12 +164,18 @@ AS BEGIN SET NOCOUNT ON; - SELECT DISTINCT TOP 100 - [项目号] - FROM [dbo].[MES_设计报工_任务] + SELECT DISTINCT TOP 200 + CAST([项目代码] AS nvarchar(100)) AS [项目号], + CAST([项目名称] AS nvarchar(200)) AS [项目名称] + FROM [SAP].[SBO_YL].[dbo].[VIEW_OPRJ] WHERE - ISNULL([项目号], N'') <> N'' - AND (ISNULL(@过滤, N'') = N'' OR [项目号] LIKE N'%' + @过滤 + N'%') + ISNULL([项目代码], N'') <> N'' + AND + ( + ISNULL(@过滤, N'') = N'' + OR CAST([项目代码] AS nvarchar(100)) LIKE N'%' + @过滤 + N'%' + OR CAST(ISNULL([项目名称], N'') AS nvarchar(200)) LIKE N'%' + @过滤 + N'%' + ) ORDER BY [项目号]; END GO @@ -172,12 +185,15 @@ CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_查询] @项目号 nvarchar(100) = N'', @物料编码 nvarchar(100) = N'', @图号 nvarchar(100) = N'', + @类别 nvarchar(100) = N'', @关联父件物料编码 nvarchar(100) = N'', @预计开始时间_Start nvarchar(30) = N'', @预计开始时间_End nvarchar(30) = N'', @预计结束时间_Start nvarchar(30) = N'', @预计结束时间_End nvarchar(30) = N'', - @单据状态 nvarchar(50) = N'' + @单据状态 nvarchar(50) = N'', + @当前操作人ID nvarchar(100) = N'', + @当前操作人 nvarchar(100) = N'' AS BEGIN SET NOCOUNT ON; @@ -193,6 +209,7 @@ BEGIN t.[物料编码], t.[物料名称], t.[图号], + t.[类别], t.[任务描述], t.[关联父件物料编码], t.[关联父件物料名称], @@ -211,6 +228,8 @@ BEGIN t.[备注], ISNULL(r.[报工次数], 0) AS [报工次数], ISNULL(r.[未结束报工数], 0) AS [未结束报工数], + ISNULL(r.[当前用户未结束报工数], 0) AS [当前用户未结束报工数], + ISNULL(p.[未结束报工人员], N'') AS [未结束报工人员], CONVERT(varchar(19), r.[最后开始时间], 120) AS [最后开始时间], CONVERT(varchar(19), r.[最后结束时间], 120) AS [最后结束时间] FROM [dbo].[MES_设计报工_任务] AS t @@ -219,16 +238,35 @@ BEGIN SELECT COUNT(1) AS [报工次数], SUM(CASE WHEN rr.[结束时间] IS NULL THEN 1 ELSE 0 END) AS [未结束报工数], + SUM(CASE + WHEN rr.[结束时间] IS NULL + AND ( + (NULLIF(@当前操作人ID, N'') IS NOT NULL AND ISNULL(rr.[操作人ID], N'') = @当前操作人ID) + OR (NULLIF(@当前操作人ID, N'') IS NULL AND NULLIF(@当前操作人, N'') IS NOT NULL AND ISNULL(rr.[操作人], N'') = @当前操作人) + ) + THEN 1 ELSE 0 END) AS [当前用户未结束报工数], MAX(rr.[开始时间]) AS [最后开始时间], MAX(rr.[结束时间]) AS [最后结束时间] FROM [dbo].[MES_设计报工_记录] AS rr WHERE rr.[DID] = t.[DID] ) AS r + OUTER APPLY + ( + SELECT STRING_AGG(CONVERT(nvarchar(max), x.[操作人标识]), N'、') AS [未结束报工人员] + FROM + ( + SELECT DISTINCT COALESCE(NULLIF(rr2.[操作人], N''), NULLIF(rr2.[操作人ID], N''), N'未填写操作人') AS [操作人标识] + FROM [dbo].[MES_设计报工_记录] AS rr2 + WHERE rr2.[DID] = t.[DID] + AND rr2.[结束时间] IS NULL + ) AS x + ) AS p WHERE (@DID IS NULL OR @DID = 0 OR t.[DID] = @DID) AND (ISNULL(@项目号, N'') = N'' OR t.[项目号] LIKE N'%' + @项目号 + N'%') AND (ISNULL(@物料编码, N'') = N'' OR t.[物料编码] LIKE N'%' + @物料编码 + N'%') AND (ISNULL(@图号, N'') = N'' OR t.[图号] LIKE N'%' + @图号 + N'%') + AND (ISNULL(@类别, N'') = N'' OR t.[类别] LIKE N'%' + @类别 + N'%') AND (ISNULL(@关联父件物料编码, N'') = N'' OR t.[关联父件物料编码] LIKE N'%' + @关联父件物料编码 + N'%') AND (ISNULL(@单据状态, N'') = N'' OR @单据状态 = N'全部' OR t.[单据状态] = @单据状态) AND (@预计开始日期1 IS NULL OR t.[预计开始时间] >= @预计开始日期1) @@ -244,6 +282,7 @@ CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_新增] @物料编码 nvarchar(100) = N'', @物料名称 nvarchar(200) = N'', @图号 nvarchar(100) = N'', + @类别 nvarchar(100) = N'', @任务描述 nvarchar(500) = N'', @关联父件物料编码 nvarchar(100) = N'', @关联父件物料名称 nvarchar(200) = N'', @@ -262,7 +301,7 @@ BEGIN INSERT INTO [dbo].[MES_设计报工_任务] ( - [项目号], [物料编码], [物料名称], [图号], [任务描述], + [项目号], [物料编码], [物料名称], [图号], [类别], [任务描述], [关联父件物料编码], [关联父件物料名称], [设计要求], [研发立项号], [研发目的], [指派对象ID], [指派对象], [预计开始时间], [预计结束时间], [单据状态], @@ -270,7 +309,7 @@ BEGIN ) VALUES ( - NULLIF(@项目号, N''), NULLIF(@物料编码, N''), NULLIF(@物料名称, N''), NULLIF(@图号, N''), NULLIF(@任务描述, N''), + NULLIF(@项目号, N''), NULLIF(@物料编码, N''), NULLIF(@物料名称, N''), NULLIF(@图号, N''), NULLIF(@类别, N''), NULLIF(@任务描述, N''), NULLIF(@关联父件物料编码, N''), NULLIF(@关联父件物料名称, N''), NULLIF(@设计要求, N''), NULLIF(@研发立项号, N''), NULLIF(@研发目的, N''), NULLIF(@指派对象ID, N''), NULLIF(@指派对象, N''), TRY_CONVERT(datetime, NULLIF(@预计开始时间, N'')), TRY_CONVERT(datetime, NULLIF(@预计结束时间, N'')), N'待开始', @@ -287,6 +326,7 @@ CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_编辑] @物料编码 nvarchar(100) = N'', @物料名称 nvarchar(200) = N'', @图号 nvarchar(100) = N'', + @类别 nvarchar(100) = N'', @任务描述 nvarchar(500) = N'', @关联父件物料编码 nvarchar(100) = N'', @关联父件物料名称 nvarchar(200) = N'', @@ -315,6 +355,7 @@ BEGIN [物料编码] = NULLIF(@物料编码, N''), [物料名称] = NULLIF(@物料名称, N''), [图号] = NULLIF(@图号, N''), + [类别] = NULLIF(@类别, N''), [任务描述] = NULLIF(@任务描述, N''), [关联父件物料编码] = NULLIF(@关联父件物料编码, N''), [关联父件物料名称] = NULLIF(@关联父件物料名称, N''), @@ -340,16 +381,70 @@ AS BEGIN SET NOCOUNT ON; - IF EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_记录] WHERE [DID] = @DID) - BEGIN - SELECT CAST(0 AS int) AS [result], N'该任务已有设计报工记录,不能删除' AS [message]; - RETURN; - END + DECLARE @单据状态 nvarchar(50); + DECLARE @删除行数 int; - DELETE FROM [dbo].[MES_设计报工_任务] - WHERE [DID] = @DID; + BEGIN TRY + BEGIN TRANSACTION; - SELECT CAST(1 AS int) AS [result], N'删除成功' AS [message]; + SELECT @单据状态 = [单据状态] + FROM [dbo].[MES_设计报工_任务] WITH (UPDLOCK, HOLDLOCK) + WHERE [DID] = @DID; + + IF @单据状态 IS NULL + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(0 AS int) AS [result], N'删除失败:任务不存在或已被删除' AS [message]; + RETURN; + END + + IF EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_记录] WITH (HOLDLOCK) WHERE [DID] = @DID) + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(0 AS int) AS [result], N'删除失败:该任务已有设计报工记录,不能删除' AS [message]; + RETURN; + END + + IF EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_校验记录] WITH (HOLDLOCK) WHERE [DID] = @DID) + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(0 AS int) AS [result], N'删除失败:该任务已有设计工时校验记录,不能删除' AS [message]; + RETURN; + END + + IF @单据状态 = N'已完成' + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(0 AS int) AS [result], N'删除失败:任务已完成,不能删除' AS [message]; + RETURN; + END + + IF @单据状态 <> N'待开始' + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(0 AS int) AS [result], N'删除失败:任务状态为' + @单据状态 + N',不能删除' AS [message]; + RETURN; + END + + DELETE FROM [dbo].[MES_设计报工_任务] + WHERE [DID] = @DID; + + SET @删除行数 = @@ROWCOUNT; + + IF @删除行数 <> 1 + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(0 AS int) AS [result], N'删除失败:任务不存在或已被删除' AS [message]; + RETURN; + END + + COMMIT TRANSACTION; + SELECT CAST(1 AS int) AS [result], N'删除成功' AS [message]; + END TRY + BEGIN CATCH + IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION; + SELECT CAST(0 AS int) AS [result], N'删除失败:' + ERROR_MESSAGE() AS [message]; + END CATCH END GO @@ -361,6 +456,16 @@ AS BEGIN SET NOCOUNT ON; + DECLARE @当前操作人ID nvarchar(100) = NULLIF(@操作人ID, N''); + DECLARE @当前操作人 nvarchar(100) = NULLIF(@操作人, N''); + DECLARE @RID int; + + IF @当前操作人ID IS NULL AND @当前操作人 IS NULL + BEGIN + SELECT CAST(0 AS int) AS [result], N'未获取到当前操作人,不能开始' AS [message]; + RETURN; + END + IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID) BEGIN SELECT CAST(0 AS int) AS [result], N'任务不存在' AS [message]; @@ -373,20 +478,32 @@ BEGIN RETURN; END - IF EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_记录] WHERE [DID] = @DID AND [结束时间] IS NULL) + IF EXISTS + ( + SELECT 1 + FROM [dbo].[MES_设计报工_记录] + WHERE [DID] = @DID + AND [结束时间] IS NULL + AND ( + (@当前操作人ID IS NOT NULL AND ISNULL([操作人ID], N'') = @当前操作人ID) + OR (@当前操作人ID IS NULL AND @当前操作人 IS NOT NULL AND ISNULL([操作人], N'') = @当前操作人) + ) + ) BEGIN - SELECT CAST(0 AS int) AS [result], N'该任务存在未结束的报工记录' AS [message]; + SELECT CAST(0 AS int) AS [result], N'当前人员已存在未结束的报工记录' AS [message]; RETURN; END INSERT INTO [dbo].[MES_设计报工_记录]([DID], [操作人ID], [操作人], [开始时间], [报工状态]) - VALUES(@DID, NULLIF(@操作人ID, N''), NULLIF(@操作人, N''), GETDATE(), N'执行中'); + VALUES(@DID, @当前操作人ID, @当前操作人, GETDATE(), N'执行中'); + + SET @RID = CONVERT(int, SCOPE_IDENTITY()); UPDATE [dbo].[MES_设计报工_任务] - SET [单据状态] = N'执行中', [最后编辑人] = NULLIF(@操作人, N''), [最后编辑时间] = GETDATE() + SET [单据状态] = N'执行中', [最后编辑人] = @当前操作人, [最后编辑时间] = GETDATE() WHERE [DID] = @DID; - SELECT CAST(1 AS int) AS [result], N'开始成功' AS [message], SCOPE_IDENTITY() AS [RID]; + SELECT CAST(1 AS int) AS [result], N'开始成功' AS [message], @RID AS [RID]; END GO @@ -398,15 +515,41 @@ AS BEGIN SET NOCOUNT ON; + DECLARE @当前操作人ID nvarchar(100) = NULLIF(@操作人ID, N''); + DECLARE @当前操作人 nvarchar(100) = NULLIF(@操作人, N''); DECLARE @RID int; + + IF @当前操作人ID IS NULL AND @当前操作人 IS NULL + BEGIN + SELECT CAST(0 AS int) AS [result], N'未获取到当前操作人,不能结束' AS [message]; + RETURN; + END + + IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID) + BEGIN + SELECT CAST(0 AS int) AS [result], N'任务不存在' AS [message]; + RETURN; + END + + IF EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID AND [单据状态] = N'已完成') + BEGIN + SELECT CAST(0 AS int) AS [result], N'任务已完成,不能结束' AS [message]; + RETURN; + END + SELECT TOP 1 @RID = [RID] FROM [dbo].[MES_设计报工_记录] - WHERE [DID] = @DID AND [结束时间] IS NULL + WHERE [DID] = @DID + AND [结束时间] IS NULL + AND ( + (@当前操作人ID IS NOT NULL AND ISNULL([操作人ID], N'') = @当前操作人ID) + OR (@当前操作人ID IS NULL AND @当前操作人 IS NOT NULL AND ISNULL([操作人], N'') = @当前操作人) + ) ORDER BY [开始时间] DESC, [RID] DESC; IF @RID IS NULL BEGIN - SELECT CAST(0 AS int) AS [result], N'没有未结束的报工记录' AS [message]; + SELECT CAST(0 AS int) AS [result], N'当前人员没有未结束的报工记录' AS [message]; RETURN; END @@ -418,7 +561,14 @@ BEGIN WHERE [RID] = @RID; UPDATE [dbo].[MES_设计报工_任务] - SET [单据状态] = N'已结束', [最后编辑人] = NULLIF(@操作人, N''), [最后编辑时间] = GETDATE() + SET + [单据状态] = CASE + WHEN EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_记录] WHERE [DID] = @DID AND [结束时间] IS NULL) + THEN N'执行中' + ELSE N'已结束' + END, + [最后编辑人] = @当前操作人, + [最后编辑时间] = GETDATE() WHERE [DID] = @DID AND [单据状态] <> N'已完成'; SELECT CAST(1 AS int) AS [result], N'结束成功' AS [message], @RID AS [RID]; @@ -432,15 +582,26 @@ AS BEGIN SET NOCOUNT ON; + DECLARE @未结束人员 nvarchar(max); + IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID) BEGIN SELECT CAST(0 AS int) AS [result], N'任务不存在' AS [message]; RETURN; END - IF EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_记录] WHERE [DID] = @DID AND [结束时间] IS NULL) + SELECT @未结束人员 = STRING_AGG(CONVERT(nvarchar(max), x.[操作人标识]), N'、') + FROM + ( + SELECT DISTINCT COALESCE(NULLIF([操作人], N''), NULLIF([操作人ID], N''), N'未填写操作人') AS [操作人标识] + FROM [dbo].[MES_设计报工_记录] + WHERE [DID] = @DID + AND [结束时间] IS NULL + ) AS x; + + IF NULLIF(@未结束人员, N'') IS NOT NULL BEGIN - SELECT CAST(0 AS int) AS [result], N'任务存在未结束报工,不能完成' AS [message]; + SELECT CAST(0 AS int) AS [result], N'以下人员还未点击结束:' + @未结束人员 AS [message], @未结束人员 AS [未结束人员]; RETURN; END @@ -462,6 +623,7 @@ CREATE OR ALTER PROCEDURE [dbo].[设计报工_记录_查询] @DID int = NULL, @项目号 nvarchar(100) = N'', @物料编码 nvarchar(100) = N'', + @类别 nvarchar(100) = N'', @操作人 nvarchar(100) = N'', @开始日期 nvarchar(30) = N'', @结束日期 nvarchar(30) = N'', @@ -480,6 +642,7 @@ BEGIN t.[物料编码], t.[物料名称], t.[图号], + t.[类别], t.[任务描述], t.[指派对象], r.[操作人ID], @@ -501,6 +664,7 @@ BEGIN (@DID IS NULL OR @DID = 0 OR r.[DID] = @DID) AND (ISNULL(@项目号, N'') = N'' OR t.[项目号] LIKE N'%' + @项目号 + N'%') AND (ISNULL(@物料编码, N'') = N'' OR t.[物料编码] LIKE N'%' + @物料编码 + N'%') + AND (ISNULL(@类别, N'') = N'' OR t.[类别] LIKE N'%' + @类别 + N'%') AND (ISNULL(@操作人, N'') = N'' OR r.[操作人] LIKE N'%' + @操作人 + N'%') AND (@开始 IS NULL OR r.[开始时间] >= @开始) AND (@结束 IS NULL OR r.[开始时间] < DATEADD(day, 1, @结束)) @@ -518,6 +682,7 @@ CREATE OR ALTER PROCEDURE [dbo].[设计报工_工时校验_查询] @DID int = NULL, @项目号 nvarchar(100) = N'', @物料编码 nvarchar(100) = N'', + @类别 nvarchar(100) = N'', @操作人 nvarchar(100) = N'', @开始日期 nvarchar(30) = N'', @结束日期 nvarchar(30) = N'', @@ -530,6 +695,7 @@ BEGIN @DID = @DID, @项目号 = @项目号, @物料编码 = @物料编码, + @类别 = @类别, @操作人 = @操作人, @开始日期 = @开始日期, @结束日期 = @结束日期, @@ -658,6 +824,7 @@ CREATE OR ALTER PROCEDURE [dbo].[设计报工_工时报表_作业者工时_查 @操作人 nvarchar(100) = N'', @项目号 nvarchar(100) = N'', @物料编码 nvarchar(100) = N'', + @类别 nvarchar(100) = N'', @DID int = NULL AS BEGIN @@ -677,6 +844,7 @@ BEGIN t.[物料编码], t.[物料名称], t.[图号], + t.[类别], t.[任务描述], r.[开始时间], r.[结束时间], @@ -693,6 +861,7 @@ BEGIN AND (ISNULL(@操作人, N'') = N'' OR r.[操作人] LIKE N'%' + @操作人 + N'%') AND (ISNULL(@项目号, N'') = N'' OR t.[项目号] LIKE N'%' + @项目号 + N'%') AND (ISNULL(@物料编码, N'') = N'' OR t.[物料编码] LIKE N'%' + @物料编码 + N'%') + AND (ISNULL(@类别, N'') = N'' OR t.[类别] LIKE N'%' + @类别 + N'%') AND (@DID IS NULL OR @DID = 0 OR r.[DID] = @DID) ), result AS @@ -709,6 +878,7 @@ BEGIN CAST(N'' AS nvarchar(100)) AS [物料编码], CAST(N'' AS nvarchar(200)) AS [物料名称], CAST(N'' AS nvarchar(100)) AS [图号], + CAST(N'' AS nvarchar(100)) AS [类别], CAST(N'' AS nvarchar(500)) AS [任务描述], CAST(N'' AS varchar(19)) AS [开始时间], CAST(N'' AS varchar(19)) AS [结束时间], @@ -733,6 +903,7 @@ BEGIN CAST(N'' AS nvarchar(100)) AS [物料编码], CAST(N'' AS nvarchar(200)) AS [物料名称], CAST(N'' AS nvarchar(100)) AS [图号], + CAST(N'' AS nvarchar(100)) AS [类别], CAST(N'' AS nvarchar(500)) AS [任务描述], CAST(N'' AS varchar(19)) AS [开始时间], CAST(N'' AS varchar(19)) AS [结束时间], @@ -757,6 +928,7 @@ BEGIN ISNULL([物料编码], N'') AS [物料编码], ISNULL([物料名称], N'') AS [物料名称], ISNULL([图号], N'') AS [图号], + ISNULL([类别], N'') AS [类别], ISNULL([任务描述], N'') AS [任务描述], CONVERT(varchar(19), [开始时间], 120) AS [开始时间], CONVERT(varchar(19), [结束时间], 120) AS [结束时间], diff --git a/db_backups/design_report_data_backup_20260709_110417/MES_设计报工_任务.json b/db_backups/design_report_data_backup_20260709_110417/MES_设计报工_任务.json new file mode 100644 index 0000000..1fb9f61 --- /dev/null +++ b/db_backups/design_report_data_backup_20260709_110417/MES_设计报工_任务.json @@ -0,0 +1,48 @@ +[ + { + "DID": 2, + "项目号": "CW-260001", + "物料编码": "101101-105", + "物料名称": "圆棒", + "图号": "123", + "任务描述": "测试", + "关联父件物料编码": "101101-100", + "关联父件物料名称": "圆棒", + "设计要求": "123456", + "研发立项号": "234", + "研发目的": "456", + "指派对象ID": "95,50,74", + "指派对象": "蔡根,曹元,曹作梁", + "预计开始时间": "\/Date(1783526400000)\/", + "预计结束时间": "\/Date(1783612800000)\/", + "单据状态": "已完成", + "创建日期": "\/Date(1783563588967)\/", + "创建人": "超级管理员", + "最后编辑人": "超级管理员", + "最后编辑时间": "\/Date(1783563771493)\/", + "备注": "的伟大的我无法" + }, + { + "DID": 3, + "项目号": "CW-260003", + "物料编码": "101105-30x23x72", + "物料名称": "板材", + "图号": null, + "任务描述": "测试", + "关联父件物料编码": "101101-45", + "关联父件物料名称": "圆棒", + "设计要求": null, + "研发立项号": null, + "研发目的": null, + "指派对象ID": "95,50,74", + "指派对象": "蔡根,曹元,曹作梁", + "预计开始时间": null, + "预计结束时间": null, + "单据状态": "已完成", + "创建日期": "\/Date(1783564298800)\/", + "创建人": "超级管理员", + "最后编辑人": "超级管理员", + "最后编辑时间": "\/Date(1783565606673)\/", + "备注": null + } +] diff --git a/db_backups/design_report_data_backup_20260709_110417/MES_设计报工_校验记录.json b/db_backups/design_report_data_backup_20260709_110417/MES_设计报工_校验记录.json new file mode 100644 index 0000000..87af129 --- /dev/null +++ b/db_backups/design_report_data_backup_20260709_110417/MES_设计报工_校验记录.json @@ -0,0 +1,14 @@ +{ + "VID": 1, + "RID": 2, + "DID": 2, + "校验前开始时间": "\/Date(1783563746910)\/", + "校验前结束时间": "\/Date(1783563764437)\/", + "校验后开始时间": "\/Date(1783563746000)\/", + "校验后结束时间": "\/Date(1783563808000)\/", + "校验后工时秒数": 62, + "校验人ID": "1", + "校验人": "超级管理员", + "校验时间": "\/Date(1783563815987)\/", + "校验备注": "测试" +} diff --git a/db_backups/design_report_data_backup_20260709_110417/MES_设计报工_记录.json b/db_backups/design_report_data_backup_20260709_110417/MES_设计报工_记录.json new file mode 100644 index 0000000..6037137 --- /dev/null +++ b/db_backups/design_report_data_backup_20260709_110417/MES_设计报工_记录.json @@ -0,0 +1,34 @@ +[ + { + "RID": 2, + "DID": 2, + "操作人ID": "1", + "操作人": "超级管理员", + "开始时间": "\/Date(1783563746000)\/", + "结束时间": "\/Date(1783563808000)\/", + "工时秒数": 62, + "报工状态": "已结束", + "已校验": true, + "校验人ID": "1", + "校验人": "超级管理员", + "校验时间": "\/Date(1783563815990)\/", + "创建时间": "\/Date(1783563746910)\/", + "备注": "测试" + }, + { + "RID": 3, + "DID": 3, + "操作人ID": "1", + "操作人": "超级管理员", + "开始时间": "\/Date(1783564338263)\/", + "结束时间": "\/Date(1783565595690)\/", + "工时秒数": 1257, + "报工状态": "已结束", + "已校验": false, + "校验人ID": null, + "校验人": null, + "校验时间": null, + "创建时间": "\/Date(1783564338263)\/", + "备注": null + } +] diff --git a/db_backups/design_report_data_backup_20260709_110417/_summary.json b/db_backups/design_report_data_backup_20260709_110417/_summary.json new file mode 100644 index 0000000..3ff84e9 --- /dev/null +++ b/db_backups/design_report_data_backup_20260709_110417/_summary.json @@ -0,0 +1,17 @@ +[ + { + "表名": "MES_设计报工_任务", + "行数": 2, + "备份文件": "C:\\WorkYuanLy\\MES_Manage_View_V20\\db_backups\\design_report_data_backup_20260709_110417\\MES_设计报工_任务.json" + }, + { + "表名": "MES_设计报工_记录", + "行数": 2, + "备份文件": "C:\\WorkYuanLy\\MES_Manage_View_V20\\db_backups\\design_report_data_backup_20260709_110417\\MES_设计报工_记录.json" + }, + { + "表名": "MES_设计报工_校验记录", + "行数": 1, + "备份文件": "C:\\WorkYuanLy\\MES_Manage_View_V20\\db_backups\\design_report_data_backup_20260709_110417\\MES_设计报工_校验记录.json" + } +] diff --git a/db_backups/fix_design_report_complete_guard_20260709.sql b/db_backups/fix_design_report_complete_guard_20260709.sql new file mode 100644 index 0000000..ad07392 --- /dev/null +++ b/db_backups/fix_design_report_complete_guard_20260709.sql @@ -0,0 +1,242 @@ +USE [YL_MESDB]; +GO + +CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_开始] + @DID int, + @操作人ID nvarchar(100) = N'', + @操作人 nvarchar(100) = N'' +AS +BEGIN + SET NOCOUNT ON; + SET XACT_ABORT OFF; + + DECLARE @当前操作人ID nvarchar(100) = NULLIF(@操作人ID, N''); + DECLARE @当前操作人 nvarchar(100) = NULLIF(@操作人, N''); + DECLARE @RID int; + DECLARE @初始事务数 int = @@TRANCOUNT; + DECLARE @保存点名称 sysname = N'DRT_Task_Start'; + + IF @当前操作人ID IS NULL AND @当前操作人 IS NULL + BEGIN + SELECT CAST(0 AS int) AS [result], N'未获取到当前操作人,不能开始' AS [message]; + RETURN; + END + + BEGIN TRY + IF @初始事务数 = 0 BEGIN TRANSACTION; + ELSE SAVE TRANSACTION @保存点名称; + + IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WITH (UPDLOCK, HOLDLOCK) WHERE [DID] = @DID) + BEGIN + IF @初始事务数 = 0 ROLLBACK TRANSACTION; + ELSE ROLLBACK TRANSACTION @保存点名称; + SELECT CAST(0 AS int) AS [result], N'任务不存在' AS [message]; + RETURN; + END + + IF EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID AND [单据状态] = N'已完成') + BEGIN + IF @初始事务数 = 0 ROLLBACK TRANSACTION; + ELSE ROLLBACK TRANSACTION @保存点名称; + SELECT CAST(0 AS int) AS [result], N'任务已完成,不能开始' AS [message]; + RETURN; + END + + IF EXISTS + ( + SELECT 1 + FROM [dbo].[MES_设计报工_记录] WITH (UPDLOCK, HOLDLOCK) + WHERE [DID] = @DID + AND [结束时间] IS NULL + AND ( + (@当前操作人ID IS NOT NULL AND ISNULL([操作人ID], N'') = @当前操作人ID) + OR (@当前操作人ID IS NULL AND @当前操作人 IS NOT NULL AND ISNULL([操作人], N'') = @当前操作人) + ) + ) + BEGIN + IF @初始事务数 = 0 ROLLBACK TRANSACTION; + ELSE ROLLBACK TRANSACTION @保存点名称; + SELECT CAST(0 AS int) AS [result], N'当前人员已存在未结束的报工记录' AS [message]; + RETURN; + END + + INSERT INTO [dbo].[MES_设计报工_记录]([DID], [操作人ID], [操作人], [开始时间], [报工状态]) + VALUES(@DID, @当前操作人ID, @当前操作人, GETDATE(), N'执行中'); + + SET @RID = CONVERT(int, SCOPE_IDENTITY()); + + UPDATE [dbo].[MES_设计报工_任务] + SET [单据状态] = N'执行中', [最后编辑人] = @当前操作人, [最后编辑时间] = GETDATE() + WHERE [DID] = @DID; + + IF @初始事务数 = 0 COMMIT TRANSACTION; + SELECT CAST(1 AS int) AS [result], N'开始成功' AS [message], @RID AS [RID]; + END TRY + BEGIN CATCH + IF XACT_STATE() <> 0 + BEGIN + IF @初始事务数 = 0 ROLLBACK TRANSACTION; + ELSE IF XACT_STATE() = 1 ROLLBACK TRANSACTION @保存点名称; + END + SELECT CAST(0 AS int) AS [result], ERROR_MESSAGE() AS [message]; + END CATCH +END +GO + +CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_结束] + @DID int, + @操作人ID nvarchar(100) = N'', + @操作人 nvarchar(100) = N'' +AS +BEGIN + SET NOCOUNT ON; + SET XACT_ABORT OFF; + + DECLARE @当前操作人ID nvarchar(100) = NULLIF(@操作人ID, N''); + DECLARE @当前操作人 nvarchar(100) = NULLIF(@操作人, N''); + DECLARE @RID int; + DECLARE @初始事务数 int = @@TRANCOUNT; + DECLARE @保存点名称 sysname = N'DRT_Task_End'; + + IF @当前操作人ID IS NULL AND @当前操作人 IS NULL + BEGIN + SELECT CAST(0 AS int) AS [result], N'未获取到当前操作人,不能结束' AS [message]; + RETURN; + END + + BEGIN TRY + IF @初始事务数 = 0 BEGIN TRANSACTION; + ELSE SAVE TRANSACTION @保存点名称; + + IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WITH (UPDLOCK, HOLDLOCK) WHERE [DID] = @DID) + BEGIN + IF @初始事务数 = 0 ROLLBACK TRANSACTION; + ELSE ROLLBACK TRANSACTION @保存点名称; + SELECT CAST(0 AS int) AS [result], N'任务不存在' AS [message]; + RETURN; + END + + SELECT TOP 1 @RID = [RID] + FROM [dbo].[MES_设计报工_记录] WITH (UPDLOCK, HOLDLOCK) + WHERE [DID] = @DID + AND [结束时间] IS NULL + AND ( + (@当前操作人ID IS NOT NULL AND ISNULL([操作人ID], N'') = @当前操作人ID) + OR (@当前操作人ID IS NULL AND @当前操作人 IS NOT NULL AND ISNULL([操作人], N'') = @当前操作人) + ) + ORDER BY [开始时间] DESC, [RID] DESC; + + IF @RID IS NULL + BEGIN + IF @初始事务数 = 0 ROLLBACK TRANSACTION; + ELSE ROLLBACK TRANSACTION @保存点名称; + SELECT CAST(0 AS int) AS [result], N'当前人员没有未结束的报工记录' AS [message]; + RETURN; + END + + UPDATE [dbo].[MES_设计报工_记录] + SET + [结束时间] = GETDATE(), + [工时秒数] = DATEDIFF(second, [开始时间], GETDATE()), + [报工状态] = N'已结束' + WHERE [RID] = @RID; + + UPDATE [dbo].[MES_设计报工_任务] + SET + [单据状态] = CASE + WHEN [单据状态] = N'已完成' THEN N'已完成' + WHEN EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_记录] WHERE [DID] = @DID AND [结束时间] IS NULL) THEN N'执行中' + ELSE N'已结束' + END, + [最后编辑人] = @当前操作人, + [最后编辑时间] = GETDATE() + WHERE [DID] = @DID; + + IF @初始事务数 = 0 COMMIT TRANSACTION; + SELECT CAST(1 AS int) AS [result], N'结束成功' AS [message], @RID AS [RID]; + END TRY + BEGIN CATCH + IF XACT_STATE() <> 0 + BEGIN + IF @初始事务数 = 0 ROLLBACK TRANSACTION; + ELSE IF XACT_STATE() = 1 ROLLBACK TRANSACTION @保存点名称; + END + SELECT CAST(0 AS int) AS [result], ERROR_MESSAGE() AS [message]; + END CATCH +END +GO + +CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_完成] + @DID int, + @操作人 nvarchar(100) = N'' +AS +BEGIN + SET NOCOUNT ON; + SET XACT_ABORT OFF; + + DECLARE @未结束人员 nvarchar(max); + DECLARE @初始事务数 int = @@TRANCOUNT; + DECLARE @保存点名称 sysname = N'DRT_Task_Complete'; + + BEGIN TRY + IF @初始事务数 = 0 BEGIN TRANSACTION; + ELSE SAVE TRANSACTION @保存点名称; + + IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WITH (UPDLOCK, HOLDLOCK) WHERE [DID] = @DID) + BEGIN + IF @初始事务数 = 0 ROLLBACK TRANSACTION; + ELSE ROLLBACK TRANSACTION @保存点名称; + SELECT CAST(0 AS int) AS [result], N'任务不存在' AS [message]; + RETURN; + END + + SELECT @未结束人员 = STRING_AGG(CONVERT(nvarchar(max), x.[操作人标识]), N'、') + FROM + ( + SELECT DISTINCT COALESCE(NULLIF([操作人], N''), NULLIF([操作人ID], N''), N'未填写操作人') AS [操作人标识] + FROM [dbo].[MES_设计报工_记录] WITH (UPDLOCK, HOLDLOCK) + WHERE [DID] = @DID + AND [结束时间] IS NULL + ) AS x; + + IF NULLIF(@未结束人员, N'') IS NOT NULL + BEGIN + IF @初始事务数 = 0 ROLLBACK TRANSACTION; + ELSE ROLLBACK TRANSACTION @保存点名称; + SELECT CAST(0 AS int) AS [result], N'以下人员还未点击结束:' + @未结束人员 AS [message], @未结束人员 AS [未结束人员]; + RETURN; + END + + IF EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID AND [单据状态] = N'已完成') + BEGIN + IF @初始事务数 = 0 ROLLBACK TRANSACTION; + ELSE ROLLBACK TRANSACTION @保存点名称; + SELECT CAST(0 AS int) AS [result], N'任务已完成' AS [message]; + RETURN; + END + + IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_记录] WITH (HOLDLOCK) WHERE [DID] = @DID AND [结束时间] IS NOT NULL) + BEGIN + IF @初始事务数 = 0 ROLLBACK TRANSACTION; + ELSE ROLLBACK TRANSACTION @保存点名称; + SELECT CAST(0 AS int) AS [result], N'任务未产生已结束报工,不能完成' AS [message]; + RETURN; + END + + UPDATE [dbo].[MES_设计报工_任务] + SET [单据状态] = N'已完成', [最后编辑人] = NULLIF(@操作人, N''), [最后编辑时间] = GETDATE() + WHERE [DID] = @DID; + + IF @初始事务数 = 0 COMMIT TRANSACTION; + SELECT CAST(1 AS int) AS [result], N'完成成功' AS [message]; + END TRY + BEGIN CATCH + IF XACT_STATE() <> 0 + BEGIN + IF @初始事务数 = 0 ROLLBACK TRANSACTION; + ELSE IF XACT_STATE() = 1 ROLLBACK TRANSACTION @保存点名称; + END + SELECT CAST(0 AS int) AS [result], ERROR_MESSAGE() AS [message]; + END CATCH +END +GO diff --git a/db_backups/fix_design_report_delete_guard_20260709.sql b/db_backups/fix_design_report_delete_guard_20260709.sql new file mode 100644 index 0000000..145f819 --- /dev/null +++ b/db_backups/fix_design_report_delete_guard_20260709.sql @@ -0,0 +1,76 @@ +USE [YL_MESDB]; +GO + +CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_删除] + @DID int +AS +BEGIN + SET NOCOUNT ON; + SET XACT_ABORT ON; + + DECLARE @单据状态 nvarchar(50); + DECLARE @删除行数 int; + + BEGIN TRY + BEGIN TRANSACTION; + + SELECT @单据状态 = [单据状态] + FROM [dbo].[MES_设计报工_任务] WITH (UPDLOCK, HOLDLOCK) + WHERE [DID] = @DID; + + IF @单据状态 IS NULL + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(0 AS int) AS [result], N'删除失败:任务不存在或已被删除' AS [message]; + RETURN; + END + + IF EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_记录] WITH (HOLDLOCK) WHERE [DID] = @DID) + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(0 AS int) AS [result], N'删除失败:该任务已有设计报工记录,不能删除' AS [message]; + RETURN; + END + + IF EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_校验记录] WITH (HOLDLOCK) WHERE [DID] = @DID) + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(0 AS int) AS [result], N'删除失败:该任务已有设计工时校验记录,不能删除' AS [message]; + RETURN; + END + + IF @单据状态 = N'已完成' + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(0 AS int) AS [result], N'删除失败:任务已完成,不能删除' AS [message]; + RETURN; + END + + IF @单据状态 <> N'待开始' + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(0 AS int) AS [result], N'删除失败:任务状态为' + @单据状态 + N',不能删除' AS [message]; + RETURN; + END + + DELETE FROM [dbo].[MES_设计报工_任务] + WHERE [DID] = @DID; + + SET @删除行数 = @@ROWCOUNT; + + IF @删除行数 <> 1 + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(0 AS int) AS [result], N'删除失败:任务不存在或已被删除' AS [message]; + RETURN; + END + + COMMIT TRANSACTION; + SELECT CAST(1 AS int) AS [result], N'删除成功' AS [message]; + END TRY + BEGIN CATCH + IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION; + SELECT CAST(0 AS int) AS [result], N'删除失败:' + ERROR_MESSAGE() AS [message]; + END CATCH +END +GO diff --git a/db_backups/update_design_report_multi_person_work_20260709.sql b/db_backups/update_design_report_multi_person_work_20260709.sql new file mode 100644 index 0000000..60bfc27 --- /dev/null +++ b/db_backups/update_design_report_multi_person_work_20260709.sql @@ -0,0 +1,267 @@ +USE [YL_MESDB]; +GO + +CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_查询] + @DID int = NULL, + @项目号 nvarchar(100) = N'', + @物料编码 nvarchar(100) = N'', + @图号 nvarchar(100) = N'', + @关联父件物料编码 nvarchar(100) = N'', + @预计开始时间_Start nvarchar(30) = N'', + @预计开始时间_End nvarchar(30) = N'', + @预计结束时间_Start nvarchar(30) = N'', + @预计结束时间_End nvarchar(30) = N'', + @单据状态 nvarchar(50) = N'', + @当前操作人ID nvarchar(100) = N'', + @当前操作人 nvarchar(100) = N'' +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @预计开始日期1 datetime = TRY_CONVERT(datetime, NULLIF(@预计开始时间_Start, N'')); + DECLARE @预计开始日期2 datetime = TRY_CONVERT(datetime, NULLIF(@预计开始时间_End, N'')); + DECLARE @预计结束日期1 datetime = TRY_CONVERT(datetime, NULLIF(@预计结束时间_Start, N'')); + DECLARE @预计结束日期2 datetime = TRY_CONVERT(datetime, NULLIF(@预计结束时间_End, N'')); + + SELECT TOP 1000 + t.[DID], + t.[项目号], + t.[物料编码], + t.[物料名称], + t.[图号], + t.[任务描述], + t.[关联父件物料编码], + t.[关联父件物料名称], + t.[设计要求], + t.[研发立项号], + t.[研发目的], + t.[指派对象ID], + t.[指派对象], + CONVERT(varchar(19), t.[预计开始时间], 120) AS [预计开始时间], + CONVERT(varchar(19), t.[预计结束时间], 120) AS [预计结束时间], + t.[单据状态], + CONVERT(varchar(19), t.[创建日期], 120) AS [创建日期], + t.[创建人], + t.[最后编辑人], + CONVERT(varchar(19), t.[最后编辑时间], 120) AS [最后编辑时间], + t.[备注], + ISNULL(r.[报工次数], 0) AS [报工次数], + ISNULL(r.[未结束报工数], 0) AS [未结束报工数], + ISNULL(r.[当前用户未结束报工数], 0) AS [当前用户未结束报工数], + ISNULL(p.[未结束报工人员], N'') AS [未结束报工人员], + CONVERT(varchar(19), r.[最后开始时间], 120) AS [最后开始时间], + CONVERT(varchar(19), r.[最后结束时间], 120) AS [最后结束时间] + FROM [dbo].[MES_设计报工_任务] AS t + OUTER APPLY + ( + SELECT + COUNT(1) AS [报工次数], + SUM(CASE WHEN rr.[结束时间] IS NULL THEN 1 ELSE 0 END) AS [未结束报工数], + SUM(CASE + WHEN rr.[结束时间] IS NULL + AND ( + (NULLIF(@当前操作人ID, N'') IS NOT NULL AND ISNULL(rr.[操作人ID], N'') = @当前操作人ID) + OR (NULLIF(@当前操作人ID, N'') IS NULL AND NULLIF(@当前操作人, N'') IS NOT NULL AND ISNULL(rr.[操作人], N'') = @当前操作人) + ) + THEN 1 ELSE 0 END) AS [当前用户未结束报工数], + MAX(rr.[开始时间]) AS [最后开始时间], + MAX(rr.[结束时间]) AS [最后结束时间] + FROM [dbo].[MES_设计报工_记录] AS rr + WHERE rr.[DID] = t.[DID] + ) AS r + OUTER APPLY + ( + SELECT STRING_AGG(CONVERT(nvarchar(max), x.[操作人标识]), N'、') AS [未结束报工人员] + FROM + ( + SELECT DISTINCT COALESCE(NULLIF(rr2.[操作人], N''), NULLIF(rr2.[操作人ID], N''), N'未填写操作人') AS [操作人标识] + FROM [dbo].[MES_设计报工_记录] AS rr2 + WHERE rr2.[DID] = t.[DID] + AND rr2.[结束时间] IS NULL + ) AS x + ) AS p + WHERE + (@DID IS NULL OR @DID = 0 OR t.[DID] = @DID) + AND (ISNULL(@项目号, N'') = N'' OR t.[项目号] LIKE N'%' + @项目号 + N'%') + AND (ISNULL(@物料编码, N'') = N'' OR t.[物料编码] LIKE N'%' + @物料编码 + N'%') + AND (ISNULL(@图号, N'') = N'' OR t.[图号] LIKE N'%' + @图号 + N'%') + AND (ISNULL(@关联父件物料编码, N'') = N'' OR t.[关联父件物料编码] LIKE N'%' + @关联父件物料编码 + N'%') + AND (ISNULL(@单据状态, N'') = N'' OR @单据状态 = N'全部' OR t.[单据状态] = @单据状态) + AND (@预计开始日期1 IS NULL OR t.[预计开始时间] >= @预计开始日期1) + AND (@预计开始日期2 IS NULL OR t.[预计开始时间] < DATEADD(day, 1, @预计开始日期2)) + AND (@预计结束日期1 IS NULL OR t.[预计结束时间] >= @预计结束日期1) + AND (@预计结束日期2 IS NULL OR t.[预计结束时间] < DATEADD(day, 1, @预计结束日期2)) + ORDER BY t.[DID] DESC; +END +GO + +CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_开始] + @DID int, + @操作人ID nvarchar(100) = N'', + @操作人 nvarchar(100) = N'' +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @当前操作人ID nvarchar(100) = NULLIF(@操作人ID, N''); + DECLARE @当前操作人 nvarchar(100) = NULLIF(@操作人, N''); + DECLARE @RID int; + + IF @当前操作人ID IS NULL AND @当前操作人 IS NULL + BEGIN + SELECT CAST(0 AS int) AS [result], N'未获取到当前操作人,不能开始' AS [message]; + RETURN; + END + + IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID) + BEGIN + SELECT CAST(0 AS int) AS [result], N'任务不存在' AS [message]; + RETURN; + END + + IF EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID AND [单据状态] = N'已完成') + BEGIN + SELECT CAST(0 AS int) AS [result], N'任务已完成,不能开始' AS [message]; + RETURN; + END + + IF EXISTS + ( + SELECT 1 + FROM [dbo].[MES_设计报工_记录] + WHERE [DID] = @DID + AND [结束时间] IS NULL + AND ( + (@当前操作人ID IS NOT NULL AND ISNULL([操作人ID], N'') = @当前操作人ID) + OR (@当前操作人ID IS NULL AND @当前操作人 IS NOT NULL AND ISNULL([操作人], N'') = @当前操作人) + ) + ) + BEGIN + SELECT CAST(0 AS int) AS [result], N'当前人员已存在未结束的报工记录' AS [message]; + RETURN; + END + + INSERT INTO [dbo].[MES_设计报工_记录]([DID], [操作人ID], [操作人], [开始时间], [报工状态]) + VALUES(@DID, @当前操作人ID, @当前操作人, GETDATE(), N'执行中'); + + SET @RID = CONVERT(int, SCOPE_IDENTITY()); + + UPDATE [dbo].[MES_设计报工_任务] + SET [单据状态] = N'执行中', [最后编辑人] = @当前操作人, [最后编辑时间] = GETDATE() + WHERE [DID] = @DID; + + SELECT CAST(1 AS int) AS [result], N'开始成功' AS [message], @RID AS [RID]; +END +GO + +CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_结束] + @DID int, + @操作人ID nvarchar(100) = N'', + @操作人 nvarchar(100) = N'' +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @当前操作人ID nvarchar(100) = NULLIF(@操作人ID, N''); + DECLARE @当前操作人 nvarchar(100) = NULLIF(@操作人, N''); + DECLARE @RID int; + + IF @当前操作人ID IS NULL AND @当前操作人 IS NULL + BEGIN + SELECT CAST(0 AS int) AS [result], N'未获取到当前操作人,不能结束' AS [message]; + RETURN; + END + + IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID) + BEGIN + SELECT CAST(0 AS int) AS [result], N'任务不存在' AS [message]; + RETURN; + END + + IF EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID AND [单据状态] = N'已完成') + BEGIN + SELECT CAST(0 AS int) AS [result], N'任务已完成,不能结束' AS [message]; + RETURN; + END + + SELECT TOP 1 @RID = [RID] + FROM [dbo].[MES_设计报工_记录] + WHERE [DID] = @DID + AND [结束时间] IS NULL + AND ( + (@当前操作人ID IS NOT NULL AND ISNULL([操作人ID], N'') = @当前操作人ID) + OR (@当前操作人ID IS NULL AND @当前操作人 IS NOT NULL AND ISNULL([操作人], N'') = @当前操作人) + ) + ORDER BY [开始时间] DESC, [RID] DESC; + + IF @RID IS NULL + BEGIN + SELECT CAST(0 AS int) AS [result], N'当前人员没有未结束的报工记录' AS [message]; + RETURN; + END + + UPDATE [dbo].[MES_设计报工_记录] + SET + [结束时间] = GETDATE(), + [工时秒数] = DATEDIFF(second, [开始时间], GETDATE()), + [报工状态] = N'已结束' + WHERE [RID] = @RID; + + UPDATE [dbo].[MES_设计报工_任务] + SET + [单据状态] = CASE + WHEN EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_记录] WHERE [DID] = @DID AND [结束时间] IS NULL) + THEN N'执行中' + ELSE N'已结束' + END, + [最后编辑人] = @当前操作人, + [最后编辑时间] = GETDATE() + WHERE [DID] = @DID AND [单据状态] <> N'已完成'; + + SELECT CAST(1 AS int) AS [result], N'结束成功' AS [message], @RID AS [RID]; +END +GO + +CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_完成] + @DID int, + @操作人 nvarchar(100) = N'' +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @未结束人员 nvarchar(max); + + IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID) + BEGIN + SELECT CAST(0 AS int) AS [result], N'任务不存在' AS [message]; + RETURN; + END + + SELECT @未结束人员 = STRING_AGG(CONVERT(nvarchar(max), x.[操作人标识]), N'、') + FROM + ( + SELECT DISTINCT COALESCE(NULLIF([操作人], N''), NULLIF([操作人ID], N''), N'未填写操作人') AS [操作人标识] + FROM [dbo].[MES_设计报工_记录] + WHERE [DID] = @DID + AND [结束时间] IS NULL + ) AS x; + + IF NULLIF(@未结束人员, N'') IS NOT NULL + BEGIN + SELECT CAST(0 AS int) AS [result], N'以下人员还未点击结束:' + @未结束人员 AS [message], @未结束人员 AS [未结束人员]; + RETURN; + END + + IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_记录] WHERE [DID] = @DID AND [结束时间] IS NOT NULL) + BEGIN + SELECT CAST(0 AS int) AS [result], N'任务未产生已结束报工,不能完成' AS [message]; + RETURN; + END + + UPDATE [dbo].[MES_设计报工_任务] + SET [单据状态] = N'已完成', [最后编辑人] = NULLIF(@操作人, N''), [最后编辑时间] = GETDATE() + WHERE [DID] = @DID; + + SELECT CAST(1 AS int) AS [result], N'完成成功' AS [message]; +END +GO diff --git a/db_backups/update_design_report_project_source_20260709.sql b/db_backups/update_design_report_project_source_20260709.sql new file mode 100644 index 0000000..821c98e --- /dev/null +++ b/db_backups/update_design_report_project_source_20260709.sql @@ -0,0 +1,29 @@ +USE [YL_MESDB] +GO + +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO + +CREATE OR ALTER PROCEDURE [dbo].[设计报工_项目查询] + @过滤 nvarchar(100) = N'' +AS +BEGIN + SET NOCOUNT ON; + + SELECT DISTINCT TOP 200 + CAST([项目代码] AS nvarchar(100)) AS [项目号], + CAST([项目名称] AS nvarchar(200)) AS [项目名称] + FROM [SAP].[SBO_YL].[dbo].[VIEW_OPRJ] + WHERE + ISNULL([项目代码], N'') <> N'' + AND + ( + ISNULL(@过滤, N'') = N'' + OR CAST([项目代码] AS nvarchar(100)) LIKE N'%' + @过滤 + N'%' + OR CAST(ISNULL([项目名称], N'') AS nvarchar(200)) LIKE N'%' + @过滤 + N'%' + ) + ORDER BY [项目号]; +END +GO diff --git a/doc/设计报工任务模块.docx b/doc/设计报工任务模块.docx index 1025f553066bb1b75db46ed0b68b1f49e0ee0a55..d7a275c1a458591354a0d0f7616f07dcaf9dd610 100644 GIT binary patch delta 8410 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
;4_UutdtaDGp#rJ#K%Ha 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 0`,提示 `未结束报工人员`,不调用完成过程。 +5. 新增增量脚本 `db_backups/update_design_report_multi_person_work_20260709.sql`: + - 更新 `设计报工_任务_查询`,返回 `当前用户未结束报工数` 和 `未结束报工人员`。 + - 更新 `设计报工_任务_开始`,只禁止当前人员重复开始,允许其他人员同时开始。 + - 更新 `设计报工_任务_结束`,只结束当前人员自己的未结束记录;若其他人员仍未结束,任务状态保持 `执行中`。 + - 更新 `设计报工_任务_完成`,如果存在未结束记录,返回“以下人员还未点击结束:人员名单”,不更新任务状态。 +6. 同步更新完整建库脚本 `db_backups/create_design_report_task_module_20260630.sql`,确保后续重建模块时不会丢失多人报工逻辑。 +7. 使用 `sqlcmd -f 65001` 将增量脚本发布到 `192.168.2.92 / YL_MESDB`,未在日志中记录数据库密码。 +8. 第一次事务验证时发现人员名单拼接使用 XML 方法会受到当前 SQL 执行环境 `QUOTED_IDENTIFIER` 设置影响,过程执行报错。 +9. 将人员名单拼接从 XML 方法改为 SQL Server 2019 支持的 `STRING_AGG`,重新更新增量脚本和完整建库脚本。 +10. 重新发布增量脚本到目标库。 +11. 使用事务创建临时测试任务并回滚,验证流程: + - 测试 A 点击开始成功。 + - 测试 B 点击开始成功。 + - 查询结果显示 `报工次数=2`、`未结束报工数=2`、`当前用户未结束报工数=1`、`未结束报工人员=测试A、测试B`。 + - 测试 A 点击结束成功。 + - A 结束后点击完成失败,返回“以下人员还未点击结束:测试B”。 + - 测试 B 点击结束成功。 + - A/B 都结束后点击完成成功。 + - 事务最终回滚,测试数据未保留。 +12. 执行 `npm run build`,前端构建通过,仅有项目既有资源体积和 Browserslist / baseline 数据过期 warning。 +13. 查询数据库确认 `GPT-TEST` 临时测试任务残留数为 0,并确认 `设计报工_任务_完成` 已发布为包含 `STRING_AGG` 的新定义。 + +### 修改文件 +- `src/views/ProductionManagement/DesignReportTask/Report/index.vue` +- `db_backups/update_design_report_multi_person_work_20260709.sql` +- `db_backups/create_design_report_task_module_20260630.sql` +- `gptlog-process/gpdlog.md` + +### 结论 +- 设计报工页面已支持同一任务多人分别开始、分别结束。 +- 当前人员只能结束自己的未结束报工记录,不会误结束其他人员记录。 +- 完成任务时会检查所有开始记录是否都已结束;如仍有人未结束,会提示具体人员并阻止任务完成。 +- 数据库过程已同步发布到目标库,完整建库脚本也已同步更新。 + +### 验证结果 +- 数据库事务验证通过,测试数据已回滚且无残留。 +- `npm run build` 构建通过,仅有项目既有 warning。 + +## 2026-07-09 DesignReportTask DID 3 完成误判复查与防护 + +### 用户反馈 +- 用户反馈:刚测试 DID=3 任务,点击完成时另一个人没有点结束也提示完成了;完成后另一个人点不了结束。 + +### 执行过程 +1. 查询目标库 `192.168.2.92 / YL_MESDB` 中 DID=3 的真实数据: + - `MES_设计报工_任务` 中 DID=3 状态为 `已完成`。 + - `MES_设计报工_记录` 中 DID=3 只有 1 条记录,操作人为“超级管理员”,且该记录已有结束时间。 + - DID=3 未查询到第二个人的未结束报工记录。 +2. 复查数据库过程定义: + - `设计报工_任务_完成` 已包含“以下人员还未点击结束”的拦截逻辑。 + - `设计报工_任务_结束` 已按当前人员查找未结束记录。 +3. 结论判断: + - DID=3 完成成功的直接原因是数据库中没有“另一个人”的开始记录。 + - 另一个人点不了结束,是因为 DID=3 没有该人员可结束的未结束记录,且任务已完成。 +4. 为避免页面旧数据或并发操作再次造成误判,修改 `src/views/ProductionManagement/DesignReportTask/Report/index.vue`: + - `completeTask` 改为异步方法。 + - 点击完成时新增 `getLatestTask(DID)`,先实时调用 `设计报工_任务_查询` 获取最新任务状态。 + - 完成前使用实时返回的 `未结束报工数` 和 `未结束报工人员` 判断,不再只依赖表格旧行数据。 + - 如果实时查询发现有人未结束,提示具体人员并停止调用完成过程。 + - 如果实时查询发现任务已完成,提示“任务已完成”并刷新表格。 + - 如果任务没有已结束报工,提示不能完成。 + - `canEnd` 改为只要当前用户存在未结束报工就允许点击结束,不再因为任务状态是 `已完成` 就禁用,用于修复历史异常状态下“已完成但仍有未结束记录”的结束入口。 +5. 新增数据库防护脚本 `db_backups/fix_design_report_complete_guard_20260709.sql`: + - 重新发布 `设计报工_任务_开始`、`设计报工_任务_结束`、`设计报工_任务_完成`。 + - 开始、结束、完成均对对应 DID 的任务行使用事务锁,避免完成与开始/结束并发造成状态误判。 + - 完成过程在事务内重新查询未结束人员,存在未结束记录时返回具体人员并不更新任务状态。 + - 结束过程允许历史异常状态下“任务已完成但当前人员仍有未结束记录”的人员继续结束自己的记录。 +6. 第一次事务验证时发现过程内部直接 `ROLLBACK TRANSACTION` 会回滚外层测试事务。 +7. 修改防护脚本事务写法: + - 没有外层事务时由过程自己开启并提交事务。 + - 存在外层事务时使用 `SAVE TRANSACTION` 保存点。 + - 失败时只回滚过程自己的保存点,不破坏调用方外层事务。 +8. 使用 `sqlcmd -f 65001` 发布防护脚本到目标库,日志中未记录数据库密码。 +9. 使用事务验证多人未结束完成拦截: + - 测试 A 开始成功。 + - 测试 B 开始成功。 + - 测试 A 结束成功。 + - 此时点击完成返回失败,提示“以下人员还未点击结束:测试B”。 + - 查询显示任务仍为 `执行中`,`未结束报工数=1`,`当前用户未结束报工数=1`,`未结束报工人员=测试B`。 +10. 使用事务验证历史异常状态: + - 临时创建一个状态为 `已完成` 但测试 B 仍未结束的任务。 + - 查询显示 `未结束报工数=1`、`当前用户未结束报工数=1`。 + - 测试 B 点击结束成功。 + - 结束后查询显示 `未结束报工数=0`,任务保持 `已完成`。 +11. 两组事务验证均已回滚,查询确认 `GPT-GUARD`、`GPT-BAD` 测试数据残留为 0。 +12. 执行 `npm run build`,构建通过,仅有项目既有资源体积和 Browserslist / baseline 数据过期 warning。 +13. 查询 DID=3 当前未结束记录数为 0,确认 DID=3 没有可让另一个人结束的未结束记录。 + +### 修改文件 +- `src/views/ProductionManagement/DesignReportTask/Report/index.vue` +- `db_backups/fix_design_report_complete_guard_20260709.sql` +- `gptlog-process/gpdlog.md` + +### 结论 +- DID=3 本次完成成功是因为数据库里并没有第二个人的未结束开始记录。 +- 已补充前端完成前实时查库,避免表格旧数据导致误判。 +- 已补充数据库事务锁防护,完成过程会在最终更新状态前重新检查未结束人员。 +- 已允许历史异常状态下,当前人员仍有未结束记录时可以点击结束自己的记录。 + +### 验证结果 +- DID=3 当前未结束记录数为 0。 +- 多人未结束完成拦截验证通过。 +- 历史异常已完成状态下结束验证通过。 +- 测试数据无残留。 +- `npm run build` 构建通过,仅有项目既有 warning。 + +## 2026-07-09 清空 DesignReportTask 设计报工业务数据 + +### 用户反馈 +- 用户要求:清空设计相关的数据。 + +### 执行过程 +1. 按 `DesignReportTask` 设计报工模块业务数据范围处理,未清理菜单权限、存储过程和表结构。 +2. 确认需要清空的三张业务表: + - `dbo.MES_设计报工_任务` + - `dbo.MES_设计报工_记录` + - `dbo.MES_设计报工_校验记录` +3. 清空前查询目标库 `YL_MESDB` 当前数据量: + - `MES_设计报工_任务`:2 行。 + - `MES_设计报工_记录`:2 行。 + - `MES_设计报工_校验记录`:1 行。 +4. 清空前先导出本地备份,备份目录: + - `db_backups/design_report_data_backup_20260709_110417/` +5. 备份文件包括: + - `MES_设计报工_任务.json` + - `MES_设计报工_记录.json` + - `MES_设计报工_校验记录.json` + - `_summary.json` +6. 使用事务按依赖顺序清空数据: + - 先清空 `MES_设计报工_校验记录`。 + - 再清空 `MES_设计报工_记录`。 + - 最后清空 `MES_设计报工_任务`。 +7. 清空后执行 `DBCC CHECKIDENT`,将三张表自增标识重置为 0。 +8. 再次查询三张业务表行数,确认均为 0。 +9. 查询三张表当前标识值,确认均为 0。 + +### 修改文件 +- `db_backups/design_report_data_backup_20260709_110417/MES_设计报工_任务.json` +- `db_backups/design_report_data_backup_20260709_110417/MES_设计报工_记录.json` +- `db_backups/design_report_data_backup_20260709_110417/MES_设计报工_校验记录.json` +- `db_backups/design_report_data_backup_20260709_110417/_summary.json` +- `gptlog-process/gpdlog.md` + +### 结论 +- `DesignReportTask` 设计报工模块三张业务表已清空。 +- 清空前数据已备份到本地 `db_backups/design_report_data_backup_20260709_110417/`。 +- 表结构、存储过程、菜单权限未清理。 +- 三张表自增编号已重置,后续新增数据将从 1 开始。 + +### 验证结果 +- `MES_设计报工_任务` 当前 0 行。 +- `MES_设计报工_记录` 当前 0 行。 +- `MES_设计报工_校验记录` 当前 0 行。 +- 三张表当前标识值均为 0。 + +## 2026-07-09 DesignReportTask 已完成任务禁止开始补充判断 + +### 用户反馈 +- 用户反馈:当任务状态为完成时,点击开始应该提示失败;现在任务已经被另一个人点击完成后,还能点击开始。 + +### 执行过程 +1. 检查 `src/views/ProductionManagement/DesignReportTask/Report/index.vue`。 +2. 确认页面原有 `canStart(row)` 会根据当前表格行的 `单据状态` 禁用开始按钮,但如果另一个人完成任务后当前页面未刷新,当前行仍可能是旧状态,导致用户仍能点击开始。 +3. 查询数据库过程 `dbo.设计报工_任务_开始`,确认后端已包含“任务已完成,不能开始”的拦截逻辑。 +4. 修改 `Report/index.vue` 的 `startTask(row)`: + - 将 `startTask` 改为异步方法。 + - 点击开始时先调用已有 `getLatestTask(DID)` 实时查询数据库最新任务状态。 + - 使用实时返回结果覆盖当前表格行数据。 + - 如果实时状态为 `已完成`,提示“任务已完成,不能开始”,刷新表格,并停止调用开始过程。 + - 如果当前人员已经存在未结束报工,提示“当前人员已存在未结束的报工记录”,并停止调用开始过程。 + - 只有实时状态允许开始时才调用 `设计报工_任务_开始`。 +5. 使用事务临时创建一个状态为 `已完成` 的测试任务,并调用 `设计报工_任务_开始` 验证后端返回: + - `result=0` + - `message=任务已完成,不能开始` +6. 验证事务回滚后测试数据残留数为 0。 +7. 执行 `npm run build`,构建通过,仅有项目既有资源体积和 Browserslist / baseline 数据过期 warning。 + +### 修改文件 +- `src/views/ProductionManagement/DesignReportTask/Report/index.vue` +- `gptlog-process/gpdlog.md` + +### 结论 +- 已完成任务点击“开始”时,前端会先实时查库。 +- 如果任务已被其他人完成,会立即提示“任务已完成,不能开始”,不会再调用开始过程。 +- 后端开始过程也已确认存在同样拦截,前后端均有保护。 + +### 验证结果 +- 后端模拟已完成任务点击开始,返回“任务已完成,不能开始”。 +- 测试数据无残留。 +- `npm run build` 构建通过,仅有项目既有 warning。 + +## 2026-07-09 DesignReportTask 设计任务删除失败逻辑修正 + +### 用户反馈 +- 用户反馈:设计任务删除的结果逻辑不正确。任务 1 点击删除并确认时提示“删除成功”,实际应该提示“删除失败”。 + +### 执行过程 +1. 检查 `src/views/ProductionManagement/DesignReportTask/Task/index.vue` 中 `deleteTask(row)`: + - 原逻辑确认后直接调用 `设计报工_任务_删除`。 + - 前端只按返回 `result` 判断成功或失败。 +2. 查询目标库中 DID=1 的真实数据: + - DID=1 当前状态为 `已完成`。 + - DID=1 存在 3 条 `MES_设计报工_记录`。 + - DID=1 存在 3 条 `MES_设计报工_校验记录`。 +3. 检查数据库删除过程 `dbo.设计报工_任务_删除`: + - 原过程只判断是否存在报工记录。 + - 对任务不存在、已完成状态、删除 0 行、校验记录等场景保护不足。 +4. 修改 `Task/index.vue`: + - 删除确认后先调用新增的 `getLatestTask(DID)` 实时查询数据库最新任务。 + - 如果任务不存在,提示“删除失败:任务不存在或已被删除”。 + - 如果 `报工次数 > 0`,提示“删除失败:该任务已有设计报工记录,不能删除”。 + - 如果任务状态为 `已完成`,提示“删除失败:任务已完成,不能删除”。 + - 如果任务状态不是 `待开始`,提示对应状态不能删除。 + - 只有实时查询确认可删除时,才调用 `设计报工_任务_删除`。 + - 删除调用增加异常捕获,接口异常时提示“删除失败”。 +5. 新增数据库脚本 `db_backups/fix_design_report_delete_guard_20260709.sql`: + - 重新发布 `dbo.设计报工_任务_删除`。 + - 只允许 `待开始` 且无报工记录、无校验记录的任务删除。 + - 任务不存在、已有报工、已有校验、已完成、非待开始状态、删除 0 行均返回 `result=0`。 + - 删除成功时才返回 `result=1`。 +6. 同步更新完整建库脚本 `db_backups/create_design_report_task_module_20260630.sql` 中的删除过程定义。 +7. 发布删除防护脚本到目标库 `YL_MESDB`,日志中未记录数据库密码。 +8. 验证 DID=1 删除: + - 执行 `设计报工_任务_删除 @DID=1` 返回 `result=0`。 + - 返回消息为“删除失败:该任务已有设计报工记录,不能删除”。 + - DID=1 任务仍存在。 +9. 使用事务临时创建一个 `待开始` 且无报工记录的测试任务,验证可删除场景: + - 删除过程返回 `result=1`、`message=删除成功`。 + - 事务内删除后任务残留为 0。 + - 回滚后测试数据残留为 0。 +10. 执行 `npm run build`,构建通过,仅有项目既有资源体积和 Browserslist / baseline 数据过期 warning。 + +### 修改文件 +- `src/views/ProductionManagement/DesignReportTask/Task/index.vue` +- `db_backups/fix_design_report_delete_guard_20260709.sql` +- `db_backups/create_design_report_task_module_20260630.sql` +- `gptlog-process/gpdlog.md` + +### 结论 +- 任务 1 这类已有报工记录的设计任务,现在删除时会提示删除失败。 +- 前端删除前会实时查库,不再只依赖表格旧数据。 +- 后端删除过程已补充完整保护,只允许未开始且无关联业务记录的任务删除。 + +### 验证结果 +- DID=1 删除返回失败,提示“该任务已有设计报工记录,不能删除”。 +- 可删除的待开始测试任务仍能正常删除。 +- 测试数据无残留。 +- `npm run build` 构建通过,仅有项目既有 warning。 + +## 2026-07-09 DesignReportTask 增加类别字段 + +### 用户提问 +- 用户要求:设计报工模块增加字段“类别”,类型为文本输入。 + +### 执行过程 +1. 检查 `DesignReportTask` 下四个页面: + - `Task/index.vue` + - `Report/index.vue` + - `Check/index.vue` + - `HoursReport/index.vue` +2. 确认“类别”应作为设计任务主数据字段保存,并在各业务查询中展示和筛选。 +3. 修改 `Task/index.vue`: + - 查询区增加“类别”文本输入框。 + - 表格增加“类别”列。 + - 新建/编辑设计任务弹框增加“类别”文本输入框。 + - 表单初始数据增加 `类别`。 + - 任务查询参数增加 `类别`。 + - 新增、编辑保存参数增加 `类别`。 + - 删除前实时查询任务详情时补充 `类别` 参数,避免过程参数不一致。 +4. 修改 `Report/index.vue`: + - 查询区增加“类别”文本输入框。 + - 表格增加“类别”列。 + - 报工任务查询参数增加 `类别`。 + - 开始/结束/完成前实时查询任务详情时补充 `类别` 参数。 +5. 修改 `Check/index.vue`: + - 查询区增加“类别”文本输入框。 + - 表格增加“类别”列。 + - 工时校验查询参数增加 `类别`。 +6. 修改 `HoursReport/index.vue`: + - 查询区增加“类别”文本输入框。 + - 表格增加“类别”列。 + - 工时报表查询参数增加 `类别`。 + - 树形标题中优先显示“类别 | 任务描述”,方便按类别识别任务。 +7. 修改完整建库脚本 `db_backups/create_design_report_task_module_20260630.sql`: + - `MES_设计报工_任务` 表增加 `[类别] nvarchar(100) NULL`。 + - 增加 `COL_LENGTH` 兼容判断,旧库缺少字段时自动 `ALTER TABLE`。 + - 以下过程增加 `@类别` 参数、返回字段和筛选条件: + - `设计报工_任务_查询` + - `设计报工_任务_新增` + - `设计报工_任务_编辑` + - `设计报工_记录_查询` + - `设计报工_工时校验_查询` + - `设计报工_工时报表_作业者工时_查询` +8. 新增增量脚本 `db_backups/add_design_report_category_field_20260709.sql`: + - 用于直接更新现有数据库,不重建已有业务对象。 + - 增加任务表“类别”字段。 + - 重建上述 6 个查询/新增/编辑相关过程。 +9. 将增量脚本发布到目标数据库 `192.168.2.92 / YL_MESDB`,日志中不记录数据库密码。 +10. 数据库验证: + - 检查 `MES_设计报工_任务` 中 `类别` 字段存在,结果为 `1`。 + - 检查 6 个相关存储过程均包含 `@类别` 参数和 `[类别]` 字段,结果均为 `1`。 + - 第一次事务验证时误按旧理解传入了 `@任务状态`,数据库返回该参数不存在;随后查询真实过程签名并按真实参数重新验证。 + - 第二次事务验证中执行新增,返回 `result=1`、`message=新增成功`、验证 DID 为 `6`,新增类别为 `结构`。 + - 同一事务内执行编辑,返回 `result=1`、`message=编辑成功`,编辑后类别为 `电气`。 + - 事务回滚后验证数据残留数量为 `0`。 +11. 前端静态检查: + - 使用 `rg` 和 `Select-String` 确认四个页面均存在“类别”查询输入、表格列和查询参数。 +12. 执行 `npm run build`: + - 构建通过。 + - 仅有项目既有资源体积超限 warning,以及 Browserslist / baseline-browser-mapping 数据过期提示。 + +### 修改文件 +- `src/views/ProductionManagement/DesignReportTask/Task/index.vue` +- `src/views/ProductionManagement/DesignReportTask/Report/index.vue` +- `src/views/ProductionManagement/DesignReportTask/Check/index.vue` +- `src/views/ProductionManagement/DesignReportTask/HoursReport/index.vue` +- `db_backups/create_design_report_task_module_20260630.sql` +- `db_backups/add_design_report_category_field_20260709.sql` +- `gptlog-process/gpdlog.md` + +### 结论 +- 设计报工模块已增加“类别”文本字段。 +- 新建设计任务和编辑设计任务可以录入、保存、修改“类别”。 +- 任务管理、设计报工、工时校验、工时报表四个页面均支持按“类别”筛选并展示“类别”列。 +- 数据库表和相关存储过程已同步更新到目标库。 + +### 验证结果 +- 数据库字段存在,相关存储过程均已包含“类别”。 +- 新增/编辑事务验证通过,测试数据已回滚,无残留。 +- `npm run build` 构建通过,仅有项目既有 warning。 + +## 2026-07-10 DesignReportTask Check 和 HoursReport 菜单权限补录 + +### 用户提问 +- 用户要求给 `DesignReportTask` 下 `check` 和 `HoursReport` 添加账号代码 `1` 的二级菜单权限。 +- 目标数据库为 `192.168.2.92 / YL_MESDB`,目标表为 `[dbo].[登录基础数据_二级菜单]`。 +- 数据库账号信息由用户提供,本日志不记录数据库明文密码。 + +### 执行过程 +1. 读取当前项目目录,确认存在 `gptlog-process/gpdlog.md`、`db_backups` 和 `DesignReportTask` 相关历史记录。 +2. 使用 `rg` 搜索 `登录基础数据_二级菜单`、`DesignReportTask`、`HoursReport`、`check`,确认项目内已有设计报工模块和历史菜单处理记录。 +3. 确认本机存在 `sqlcmd`,路径为 SQL Server ODBC 170 工具目录下的 `SQLCMD.EXE`。 +4. 读取 `db_backups/add_design_report_task_menu_account1_20260709.sql`,确认历史脚本中四个页面的菜单定义: + - `DesignReportTask/Task/index`:设计任务 + - `DesignReportTask/Report/index`:设计报工 + - `DesignReportTask/Check/index`:设计工时校验 + - `DesignReportTask/HoursReport/index`:设计工时报表 +5. 第一次直接读取脚本和日志时发现 PowerShell 默认编码显示中文乱码,随后改用 `Get-Content -Encoding UTF8` 重新读取,确认脚本内容和日志中文正常。 +6. 使用 `sqlcmd -f 65001` 连接目标库,查询账号代码 `1` 下 `DesignReportTask/Check/index`、`DesignReportTask/HoursReport/index`、`设计工时校验`、`设计工时报表`,执行前未查询到对应记录。 +7. 同步查询账号代码 `1` 的一级父菜单,确认“生产管理”父菜单存在且启用,`id=3`。 +8. 查询 `[dbo].[登录基础数据_二级菜单]` 表结构,确认: + - `IDD` 为 identity 字段。 + - `id` 不是 identity,需要手工维护。 + - 菜单字段包含 `pid`、`path`、`componet`、`name`、`title`、`icon`、`账号代码`、`模块代码`、`是否启用`、`操作时间` 等。 +9. 查询当前最大 `id` 为 `249`。 +10. 查询账号代码 `1` 下已有 `DesignReportTask` 菜单,确认已有: + - `id=248`,`设计任务`,`DesignReportTask/Task/index`,已启用。 + - `id=249`,`设计报工`,`DesignReportTask/Report/index`,已启用。 +11. 在事务中补录并启用两条缺失菜单: + - `id=250`,`pid=3`,`path=DesignReportTask/Check/index`,`componet=/ProductionManagement/DesignReportTask/Check/index`,`name=DesignReportCheck`,`title=设计工时校验`,`icon=PayStateSearch`,`账号代码=1`,`模块代码=250`,`是否启用=1`。 + - `id=251`,`pid=3`,`path=DesignReportTask/HoursReport/index`,`componet=/ProductionManagement/DesignReportTask/HoursReport/index`,`name=DesignReportHoursReport`,`title=设计工时报表`,`icon=DimensionsSummaryReport`,`账号代码=1`,`模块代码=251`,`是否启用=1`。 +12. 事务提交后 SQL 返回汇总:插入 `2` 条,更新启用 `2` 条,父菜单 `parent_id=3`。 +13. 再次查询账号代码 `1` 下所有 `DesignReportTask` 菜单,确认共有四条并全部启用: + - `248`:设计任务 + - `249`:设计报工 + - `250`:设计工时校验 + - `251`:设计工时报表 +14. 本次未修改前端代码和业务表结构,只修改了目标数据库中的二级菜单权限记录,并追加本日志。 + +### 结论 +- 账号代码 `1` 已补齐 `DesignReportTask` 下 `Check` 和 `HoursReport` 两个页面的二级菜单权限。 +- 两条菜单均挂在账号代码 `1` 的“生产管理”父菜单下,父菜单 `id=3`。 +- 当前账号代码 `1` 下 `DesignReportTask` 四个菜单 `Task`、`Report`、`Check`、`HoursReport` 均存在且 `是否启用=1`。 + +### 验证结果 +- `设计工时校验`:`id=250`,`pid=3`,`是否启用=1`。 +- `设计工时报表`:`id=251`,`pid=3`,`是否启用=1`。 +- 最终复查查询返回 `DesignReportTask` 四条菜单,编号为 `248` 至 `251`。 + +## 2026-07-10 上传所有修改到远程 + +### 用户提问 +- 用户要求:上传所有修改到远程。 + +### 执行过程 +1. 检查 Git 工作区状态,确认当前存在已修改、已删除和未跟踪文件。 +2. 确认当前分支为 `snapshot/local-save-20260625-154806`。 +3. 确认远程仓库为 `origin`,地址为 `http://154.8.160.151:3000/meswork/MES_Manage_View_V20.git`。 +4. 查询最近一次提交,当前 HEAD 为 `bd9ca09 feat: 增加设备数据导出`。 +5. 使用 `git status -sb` 确认当前分支跟踪 `origin/snapshot/local-save-20260625-154806`。 +6. 使用 `git branch -vv` 确认本地分支已绑定同名远程分支。 +7. 使用 `git diff --stat` 汇总已跟踪文件改动,确认包含设计报工模块前端、数据库脚本、文档、日志和设备资料目录删除等改动。 +8. 使用 `git ls-files --others --exclude-standard` 汇总未跟踪文件,确认包含 `AGENTS.md`、设计报工相关增量 SQL 脚本和数据备份 JSON。 +9. 执行 `git fetch origin` 刷新远程状态。 +10. 第一次执行上游分支检查时,PowerShell 将 `@{u}` 解析为哈希字面量导致命令失败;随后改用引号包裹 `@{u}` 重新执行。 +11. 重新确认上游分支为 `origin/snapshot/local-save-20260625-154806`。 +12. 使用 `git rev-list --left-right --count HEAD...'@{u}'` 确认本地与远程提交差异为 `0 0`,提交前不存在分叉。 +13. 使用 `git status --porcelain | Measure-Object -Line` 统计当前工作区有 `32` 条状态记录。 +14. 按日志规则先追加本条中文执行记录,本条记录将随同本次提交一起推送到远程。 +15. 后续将执行 `git add -A` 全量暂存当前可见改动,创建提交,并推送到当前跟踪远程分支。 + +### 结论 +- 已确认当前分支和远程分支未分叉,可以直接提交并推送。 +- 本次按用户“所有修改”的要求处理,不筛除当前工作区中的已修改、已删除和未跟踪文件。 +- 本日志记录会随同本次提交一起上传到远程。 diff --git a/src/views/PlanManagement/SelfMakePlando/index.vue b/src/views/PlanManagement/SelfMakePlando/index.vue index d487876..fa8b016 100644 --- a/src/views/PlanManagement/SelfMakePlando/index.vue +++ b/src/views/PlanManagement/SelfMakePlando/index.vue @@ -92,14 +92,14 @@ - + - + @@ -110,7 +110,7 @@ --> - + - + - + - + diff --git a/src/views/ProductionManagement/DesignReportTask/Check/index.vue b/src/views/ProductionManagement/DesignReportTask/Check/index.vue index 320296f..2b73490 100644 --- a/src/views/ProductionManagement/DesignReportTask/Check/index.vue +++ b/src/views/ProductionManagement/DesignReportTask/Check/index.vue @@ -5,9 +5,43 @@ 任务ID: 项目号: - + + + 物料编码: - + + + + 类别: + 操作人: 开始日期: @@ -21,7 +55,7 @@ 查询 - 批量校验 + 批量校验 + @@ -54,11 +89,13 @@ - + @@ -112,10 +149,13 @@ export default { dialogVisible: false, tableData: [], multipleSelection: [], + projectOptions: [], + materialOptions: [], searchForm: { did: '', projectNo: '', itemCode: '', + category: '', operator: '', startDate: '', endDate: '', @@ -147,14 +187,28 @@ export default { } }, created() { + this.loadDefaultProjectOptions() + this.loadDefaultMaterialOptions() this.searchTable() }, methods: { + loadDefaultProjectOptions() { + this.queryProjects('') + }, + loadDefaultMaterialOptions() { + this.queryMaterialOptions('') + }, + handleProjectVisibleChange(visible) { + if (visible && this.projectOptions.length === 0) { + this.loadDefaultProjectOptions() + } + }, buildSearchParams() { return [ ['DID', this.searchForm.did || 0], ['项目号', this.searchForm.projectNo || ''], ['物料编码', this.searchForm.itemCode || ''], + ['类别', this.searchForm.category || ''], ['操作人', this.searchForm.operator || ''], ['开始日期', this.searchForm.startDate || ''], ['结束日期', this.searchForm.endDate || ''], @@ -174,6 +228,24 @@ export default { this.loading = false } }, + async queryProjects(query) { + const data = this.CreateData('11', '设计报工_项目查询', [['过滤', query || '']]) + try { + const response = await this.ExecDatabase(data) + this.projectOptions = response.data || [] + } catch (error) { + this.projectOptions = [] + } + }, + async queryMaterialOptions(query) { + const data = this.CreateData('11', '设计报工_物料查询', [['过滤', query || '']]) + try { + const response = await this.ExecDatabase(data) + this.materialOptions = response.data || [] + } catch (error) { + this.materialOptions = [] + } + }, handleSelectionChange(selection) { this.multipleSelection = selection }, @@ -261,6 +333,12 @@ export default { }, currentUserName() { return (this.$store && this.$store.getters && this.$store.getters.name) || '' + }, + formatMaterialLabel(item) { + return item.物料名称 ? `${item.物料编码} | ${item.物料名称}` : item.物料编码 + }, + formatProjectLabel(item) { + return item.项目名称 ? `${item.项目号} | ${item.项目名称}` : item.项目号 } } } @@ -278,4 +356,24 @@ export default { .show-text { margin-right: 4px; } + +.design-action-buttons { + display: inline-flex; + align-items: center; + justify-content: center; + flex-wrap: nowrap; + gap: 10px; + width: 100%; + white-space: nowrap; +} + +.design-action-buttons ::v-deep .el-button { + margin: 0; + padding: 0; + min-width: 32px; +} + +.design-action-buttons ::v-deep .el-button + .el-button { + margin-left: 0; +} diff --git a/src/views/ProductionManagement/DesignReportTask/HoursReport/index.vue b/src/views/ProductionManagement/DesignReportTask/HoursReport/index.vue index 626b3e4..86cdf83 100644 --- a/src/views/ProductionManagement/DesignReportTask/HoursReport/index.vue +++ b/src/views/ProductionManagement/DesignReportTask/HoursReport/index.vue @@ -23,9 +23,43 @@ 操作人: 项目号: - + + + 物料编码: - + + + + 类别: + 任务ID: 查询 @@ -54,6 +88,7 @@ +