feat: 完善计划发货与设计任务功能

This commit is contained in:
2026-07-21 09:20:19 +08:00
parent e31027aa9d
commit 8fdd0b6803
11 changed files with 1845 additions and 53 deletions

View File

@@ -0,0 +1,308 @@
USE [YL_MESDB];
GO
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
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,
@ nvarchar(100) = N'',
@ nvarchar(100) = N''
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ datetime = TRY_CONVERT(datetime, NULLIF(@, N''));
DECLARE @ datetime = TRY_CONVERT(datetime, NULLIF(@, N''));
DECLARE @ bit = CASE WHEN EXISTS
(
SELECT 1
FROM [dbo].[_角色信息]
WHERE CONVERT(nvarchar(100), [Roles_number]) = @
AND ([Roles_Function] LIKE N'%领导%' OR [Roles_Function] LIKE N'%管理员%')
) THEN 1 ELSE 0 END;
;WITH base AS
(
SELECT
r.[RID],
r.[DID],
ISNULL(r.[], N'') AS [],
t.[],
t.[],
t.[],
t.[],
t.[],
t.[],
r.[],
r.[],
ISNULL(r.[], 0) AS [],
r.[],
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)
AND
(
@ = 1
OR
(
NULLIF(LTRIM(RTRIM(@)), N'') IS NOT NULL
AND
(
ISNULL(t.[], N'') = LTRIM(RTRIM(@))
OR ISNULL(r.[], N'') = LTRIM(RTRIM(@))
)
)
)
),
result AS
(
SELECT
1 AS [Level],
N't-' + CAST([DID] AS nvarchar(20)) AS [id],
CAST(N'' AS nvarchar(120)) AS [parentId],
CAST(N'' AS nvarchar(100)) AS [],
CAST(N'' AS nvarchar(20)) AS [],
CAST(NULL AS int) AS [RID],
[DID],
ISNULL(MAX([]), N'') AS [],
ISNULL(MAX([]), N'') AS [],
ISNULL(MAX([]), N'') AS [],
ISNULL(MAX([]), N'') AS [],
ISNULL(MAX([]), N'') AS [],
ISNULL(MAX([]), N'') AS [],
CONVERT(varchar(19), MIN([]), 120) AS [],
CONVERT(varchar(19), MAX([]), 120) AS [],
COUNT(1) AS [],
CAST(SUM([]) / 3600.0 AS decimal(18, 2)) AS [],
CASE
WHEN SUM(CONVERT(int, [])) = COUNT(1) THEN N'已校验'
WHEN SUM(CONVERT(int, [])) = 0 THEN N'未校验'
ELSE N'部分校验'
END AS [],
ISNULL(STRING_AGG(
CASE WHEN NULLIF(LTRIM(RTRIM([])), N'') IS NOT NULL
THEN CONVERT(nvarchar(max), CONVERT(nvarchar(19), [], 120) + NCHAR(13) + NCHAR(10) + []) END,
NCHAR(13) + NCHAR(10) + NCHAR(13) + NCHAR(10)
) WITHIN GROUP (ORDER BY [], [RID]), N'') AS [],
ISNULL(STRING_AGG(
CASE WHEN NULLIF(LTRIM(RTRIM([])), N'') IS NOT NULL
THEN CONVERT(nvarchar(max), []) END,
NCHAR(13) + NCHAR(10)
) WITHIN GROUP (ORDER BY [], [RID]), N'') AS []
FROM base
GROUP BY [DID]
UNION ALL
SELECT
2 AS [Level],
N't-' + CAST([DID] AS nvarchar(20)) + N'-o-' + [] AS [id],
N't-' + CAST([DID] AS nvarchar(20)) AS [parentId],
[],
CAST(N'' AS nvarchar(20)) AS [],
CAST(NULL AS int) AS [RID],
[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 [],
CONVERT(varchar(19), MIN([]), 120) AS [],
CONVERT(varchar(19), MAX([]), 120) AS [],
COUNT(1) AS [],
CAST(SUM([]) / 3600.0 AS decimal(18, 2)) AS [],
CASE
WHEN SUM(CONVERT(int, [])) = COUNT(1) THEN N'已校验'
WHEN SUM(CONVERT(int, [])) = 0 THEN N'未校验'
ELSE N'部分校验'
END AS [],
ISNULL(STRING_AGG(
CASE WHEN NULLIF(LTRIM(RTRIM([])), N'') IS NOT NULL
THEN CONVERT(nvarchar(max), CONVERT(nvarchar(19), [], 120) + NCHAR(13) + NCHAR(10) + []) END,
NCHAR(13) + NCHAR(10) + NCHAR(13) + NCHAR(10)
) WITHIN GROUP (ORDER BY [], [RID]), N'') AS [],
ISNULL(STRING_AGG(
CASE WHEN NULLIF(LTRIM(RTRIM([])), N'') IS NOT NULL
THEN CONVERT(nvarchar(max), []) END,
NCHAR(13) + NCHAR(10)
) WITHIN GROUP (ORDER BY [], [RID]), N'') AS []
FROM base
GROUP BY [DID], []
)
SELECT *
FROM result
ORDER BY [DID] DESC, [Level], [];
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,
@ nvarchar(100) = N'',
@ nvarchar(100) = N''
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ datetime = TRY_CONVERT(datetime, NULLIF(@, N''));
DECLARE @ datetime = TRY_CONVERT(datetime, NULLIF(@, N''));
DECLARE @ bit = CASE WHEN EXISTS
(
SELECT 1
FROM [dbo].[_角色信息]
WHERE CONVERT(nvarchar(100), [Roles_number]) = @
AND ([Roles_Function] LIKE N'%领导%' OR [Roles_Function] LIKE N'%管理员%')
) THEN 1 ELSE 0 END;
;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.[],
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)
AND
(
@ = 1
OR
(
NULLIF(LTRIM(RTRIM(@)), N'') IS NOT NULL
AND
(
ISNULL(t.[], N'') = LTRIM(RTRIM(@))
OR ISNULL(r.[], N'') = LTRIM(RTRIM(@))
)
)
)
),
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 [],
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 [],
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 [],
ISNULL([], N'') AS []
FROM base
)
SELECT *
FROM result
ORDER BY [], [], [Level], [RID];
END
GO

View File

@@ -0,0 +1,260 @@
USE [YL_MESDB];
GO
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
CREATE OR ALTER PROCEDURE [dbo].[_发货状态查询]
@ nvarchar(4000) = N'0',
@ nvarchar(4000) = N'0',
@ nvarchar(4000) = N'0',
@ nvarchar(4000) = N'0',
@ datetime = NULL,
@ nvarchar(20) = N'',
@ nvarchar(20) = N''
AS
BEGIN
SET NOCOUNT ON;
SELECT
d.[TaskAID],
STRING_AGG(CONVERT(nvarchar(max), d.[]), N',')
WITHIN GROUP (ORDER BY d.[]) AS []
INTO #当前加工操作人汇总
FROM
(
SELECT DISTINCT
[TaskAID],
NULLIF(LTRIM(RTRIM([])), N'') AS []
FROM [dbo].[YL_加工中心_操作记录表]
WHERE [] = N'开始加工'
AND [] IS NULL
AND [] LIKE N'%装配%'
AND [] IS NOT NULL
AND NULLIF(LTRIM(RTRIM([])), N'') IS NOT NULL
) AS d
GROUP BY d.[TaskAID];
CREATE UNIQUE CLUSTERED INDEX [IX_当前加工操作人汇总_TaskAID]
ON #当前加工操作人汇总 ([TaskAID]);
SELECT
[TaskAID],
SUM(CASE WHEN [] = N'终检' THEN ISNULL([], 0) ELSE 0 END) AS [],
SUM(CASE WHEN [] = N'收检' THEN ISNULL([], 0) ELSE 0 END) AS []
INTO #质检汇总
FROM [dbo].[View_质量检验_质检记录]
WHERE [] IN (N'收检', N'终检')
GROUP BY [TaskAID];
CREATE UNIQUE CLUSTERED INDEX [IX_质检汇总_TaskAID]
ON #质检汇总 ([TaskAID]);
SELECT
gs.[],
SUM(gs.[]) AS []
INTO #合同装配工时汇总
FROM [dbo].[View_生产工时视图] AS gs
INNER JOIN [dbo].[_人员信息] AS ry ON gs.[] = ry.[Personnel_Name]
WHERE ry.[] = N'装配'
GROUP BY gs.[];
CREATE INDEX [IX_合同装配工时汇总_合同号]
ON #合同装配工时汇总 ([合同号]);
;WITH AS
(
SELECT
c.[DocStatus] AS [],
c.[],
c.[],
CONVERT(nvarchar(4000), c.[]) AS [],
c.[],
c.[],
c.[],
a.[TaskAID],
COALESCE(a.[], c.[]) AS [],
COALESCE(
NULLIF(CONVERT(nvarchar(200), a.[]), N''),
NULLIF(CONVERT(nvarchar(200), c.[]), N'')
) AS [],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
CONVERT(date, a.[]) AS [],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
c.[] AS [],
a.[],
a.[],
a.[],
b.[],
ISNULL(h.[], 0) AS [],
ISNULL(q.[], 0) AS []
FROM [SAP].[SBO_YL].[dbo].[UBT_ODRF_ODLNMES] AS c
LEFT JOIN [YL_MESDB].[dbo].[View_生产订单_MES] AS a ON c.[] = a.[]
LEFT JOIN #当前加工操作人汇总 AS b ON a.[TaskAID] = b.[TaskAID]
LEFT JOIN #质检汇总 AS q ON a.[TaskAID] = q.[TaskAID]
LEFT JOIN #合同装配工时汇总 AS h ON a.[合同号] = h.[合同号]
WHERE
(
a.[TaskAID] IS NULL
OR a.[] IS NULL
OR ISNULL(q.[], 0) + ISNULL(q.[], 0) <> a.[]
OR ISNULL(q.[], 0) <> ISNULL(a.[], 0)
)
AND (@ = N'0' OR CONVERT(nvarchar(100), c.[]) LIKE N'%' + @ + N'%')
AND
(
@ = N'0'
OR COALESCE(
NULLIF(CONVERT(nvarchar(200), a.[]), N''),
NULLIF(CONVERT(nvarchar(200), c.[]), N'')
) LIKE N'%' + @ + N'%'
)
AND
(
@ = N'0'
OR ISNULL(CONVERT(nvarchar(4000), c.[]), N'') LIKE N'%' + @ + N'%'
)
AND (@ = N'0' OR ISNULL(c.[], N'') LIKE N'%' + @ + N'%')
AND (@ IS NULL OR CONVERT(date, c.[]) = CONVERT(date, @))
AND
(
ISNULL(@, N'') = N''
OR (@ = N'' AND ISNULL(a.[], 0) = 1)
OR (@ = N'' AND ISNULL(a.[], 0) <> 1)
)
AND
(
ISNULL(@, N'') = N''
OR (@ = N'发料齐套' AND (a.[] = N'发料齐套' OR ISNULL(a.[], N'') = N'1'))
OR (@ = N'发料缺件' AND (a.[] = N'发料缺件' OR ISNULL(a.[], N'') = N'2'))
OR
(
@ = N'未发料'
AND ISNULL(a.[], N'') NOT IN (N'1', N'2', N'发料齐套', N'发料缺件')
)
)
UNION ALL
SELECT
CAST(NULL AS char(1)) AS [],
a.[] AS [],
a.[],
CONVERT(nvarchar(4000), a.[]) AS [],
CAST(NULL AS numeric(19, 6)) AS [],
CAST(NULL AS datetime) AS [],
CAST(NULL AS int) AS [],
a.[TaskAID],
a.[],
CONVERT(nvarchar(200), a.[]) AS [],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
CONVERT(date, a.[]) AS [],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
b.[],
ISNULL(h.[], 0) AS [],
ISNULL(q.[], 0) AS []
FROM [YL_MESDB].[dbo].[View_生产订单_MES] AS a
LEFT JOIN #当前加工操作人汇总 AS b ON a.[TaskAID] = b.[TaskAID]
LEFT JOIN #质检汇总 AS q ON a.[TaskAID] = q.[TaskAID]
LEFT JOIN #合同装配工时汇总 AS h ON a.[合同号] = h.[合同号]
WHERE
a.[] = N''
AND a.[] LIKE N'%装配%'
AND
(
a.[] IS NULL
OR ISNULL(q.[], 0) + ISNULL(q.[], 0) <> a.[]
OR ISNULL(q.[], 0) <> ISNULL(a.[], 0)
)
AND NOT EXISTS
(
SELECT 1
FROM [SAP].[SBO_YL].[dbo].[UBT_ODRF_ODLNMES] AS c
WHERE c.[] = a.[]
)
AND (@ = N'0' OR CONVERT(nvarchar(100), a.[]) LIKE N'%' + @ + N'%')
AND (@ = N'0' OR ISNULL(CONVERT(nvarchar(200), a.[]), N'') LIKE N'%' + @ + N'%')
AND (@ = N'0' OR ISNULL(a.[], N'') LIKE N'%' + @ + N'%')
AND (@ = N'0' OR ISNULL(a.[], N'') LIKE N'%' + @ + N'%')
AND (@ IS NULL OR CONVERT(date, a.[]) = CONVERT(date, @))
AND
(
ISNULL(@, N'') = N''
OR (@ = N'' AND ISNULL(a.[], 0) = 1)
OR (@ = N'' AND ISNULL(a.[], 0) <> 1)
)
AND
(
ISNULL(@, N'') = N''
OR (@ = N'发料齐套' AND (a.[] = N'发料齐套' OR ISNULL(a.[], N'') = N'1'))
OR (@ = N'发料缺件' AND (a.[] = N'发料缺件' OR ISNULL(a.[], N'') = N'2'))
OR
(
@ = N'未发料'
AND ISNULL(a.[], N'') NOT IN (N'1', N'2', N'发料齐套', N'发料缺件')
)
)
)
SELECT *
FROM
ORDER BY
CASE WHEN [] IS NULL THEN 1 ELSE 0 END,
[],
[],
[],
[];
END
GO

View File

@@ -0,0 +1,209 @@
USE [YL_MESDB];
GO
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
CREATE OR ALTER PROCEDURE [dbo].[_发货状态查询]
@ nvarchar(4000) = N'0',
@ nvarchar(4000) = N'0',
@ nvarchar(4000) = N'0',
@ nvarchar(4000) = N'0',
@ datetime = NULL,
@ nvarchar(20) = N'',
@ nvarchar(20) = N''
AS
BEGIN
SET NOCOUNT ON;
;WITH AS
(
SELECT DISTINCT
[TaskAID],
NULLIF(LTRIM(RTRIM([])), N'') AS []
FROM [dbo].[YL_加工中心_操作记录表]
WHERE NULLIF(LTRIM(RTRIM([])), N'') IS NOT NULL
),
AS
(
SELECT
[TaskAID],
STRING_AGG(CONVERT(nvarchar(max), []), N',')
WITHIN GROUP (ORDER BY []) AS []
FROM
GROUP BY [TaskAID]
),
AS
(
SELECT
[TaskAID],
SUM(ISNULL([], 0)) AS []
FROM [dbo].[View_质量检验_质检记录]
GROUP BY [TaskAID]
),
AS
(
SELECT
gs.[],
SUM(gs.[]) AS []
FROM [dbo].[View_生产工时视图] AS gs
INNER JOIN [dbo].[_人员信息] AS ry ON gs.[] = ry.[Personnel_Name]
WHERE ry.[] = N'装配'
GROUP BY gs.[]
)
SELECT
c.[DocStatus] AS [],
c.[],
c.[],
CONVERT(nvarchar(4000), c.[]) AS [],
c.[],
c.[],
c.[],
a.[TaskAID],
COALESCE(a.[], c.[]) AS [],
COALESCE(
NULLIF(CONVERT(nvarchar(200), a.[]), N''),
NULLIF(CONVERT(nvarchar(200), c.[]), N'')
) AS [],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
c.[] AS [],
a.[],
a.[],
a.[],
b.[],
ISNULL(h.[], 0) AS [],
ISNULL(q.[], 0) AS []
FROM [SAP].[SBO_YL].[dbo].[UBT_ODRF_ODLNMES] AS c
LEFT JOIN [YL_MESDB].[dbo].[View_生产订单_MES] AS a ON c.[] = a.[]
LEFT JOIN AS b ON a.[TaskAID] = b.[TaskAID]
LEFT JOIN AS q ON a.[TaskAID] = q.[TaskAID]
LEFT JOIN AS h ON a.[] = h.[]
WHERE
(@ = N'0' OR CONVERT(nvarchar(100), c.[]) LIKE N'%' + @ + N'%')
AND
(
@ = N'0'
OR COALESCE(
NULLIF(CONVERT(nvarchar(200), a.[]), N''),
NULLIF(CONVERT(nvarchar(200), c.[]), N'')
) LIKE N'%' + @ + N'%'
)
AND
(
@ = N'0'
OR ISNULL(CONVERT(nvarchar(4000), c.[]), N'') LIKE N'%' + @ + N'%'
)
AND (@ = N'0' OR ISNULL(c.[], N'') LIKE N'%' + @ + N'%')
AND (@ IS NULL OR CONVERT(date, c.[]) = CONVERT(date, @))
AND
(
ISNULL(@, N'') = N''
OR a.[TaskAID] IS NULL
OR (@ = N'' AND ISNULL(a.[], 0) = 1)
OR (@ = N'' AND ISNULL(a.[], 0) <> 1)
)
AND
(
ISNULL(@, N'') = N''
OR a.[TaskAID] IS NULL
OR (@ = N'发料齐套' AND (a.[] = N'发料齐套' OR ISNULL(a.[], N'') = N'1'))
OR (@ = N'发料缺件' AND (a.[] = N'发料缺件' OR ISNULL(a.[], N'') = N'2'))
OR
(
@ = N'未发料'
AND ISNULL(a.[], N'') NOT IN (N'1', N'2', N'发料齐套', N'发料缺件')
)
)
UNION ALL
SELECT
CAST(NULL AS char(1)) AS [],
a.[] AS [],
a.[],
CONVERT(nvarchar(4000), a.[]) AS [],
CAST(NULL AS numeric(19, 6)) AS [],
CAST(NULL AS datetime) AS [],
CAST(NULL AS int) AS [],
a.[TaskAID],
a.[],
CONVERT(nvarchar(200), a.[]) AS [],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
a.[],
b.[],
ISNULL(h.[], 0) AS [],
ISNULL(q.[], 0) AS []
FROM [YL_MESDB].[dbo].[View_生产订单_MES] AS a
LEFT JOIN AS b ON a.[TaskAID] = b.[TaskAID]
LEFT JOIN AS q ON a.[TaskAID] = q.[TaskAID]
LEFT JOIN AS h ON a.[] = h.[]
WHERE
a.[] = N''
AND a.[] LIKE N'%装配%'
AND NOT EXISTS
(
SELECT 1
FROM [SAP].[SBO_YL].[dbo].[UBT_ODRF_ODLNMES] AS c
WHERE c.[] = a.[]
)
AND (@ = N'0' OR CONVERT(nvarchar(100), a.[]) LIKE N'%' + @ + N'%')
AND (@ = N'0' OR ISNULL(CONVERT(nvarchar(200), a.[]), N'') LIKE N'%' + @ + N'%')
AND (@ = N'0' OR ISNULL(a.[], N'') LIKE N'%' + @ + N'%')
AND (@ = N'0' OR ISNULL(a.[], N'') LIKE N'%' + @ + N'%')
AND (@ IS NULL OR CONVERT(date, a.[]) = CONVERT(date, @))
ORDER BY [], [], [];
END
GO

View File

@@ -4020,3 +4020,858 @@ pm run build通过仅有既有警告。
- 设计任务和设计报工列表中的普通字段、编号和历史内容均按列宽自动换行。 - 设计任务和设计报工列表中的普通字段、编号和历史内容均按列宽自动换行。
- 列表不再使用省略号,也不再裁剪超过三行的历史内容。 - 列表不再使用省略号,也不再裁剪超过三行的历史内容。
- 108 像素作为基础行高保留,内容较多时表格行会继续增长并完整显示。 - 108 像素作为基础行高保留,内容较多时表格行会继续增长并完整显示。
### 验证结果
- 两个目标 Vue 文件 ESLint 通过。
- 目标文件差异空白检查通过。
- 自动换行和取消省略样式检查通过。
- 历史内容最大高度及省略号残留检查无命中。
- `npm run build` 生产构建通过。
- `https://localhost:1997/` 返回 HTTP 200。
## 2026-07-17 上传当前全部修改到远程仓库
### 用户提问
- 用户要求将当前工作区的所有修改上传到远程仓库。
### 执行过程
1. 检查 Git 工作区、当前分支、跟踪分支和远程地址,确认当前分支为 `snapshot/local-save-20260625-154806`,跟踪 `origin/snapshot/local-save-20260625-154806`
2. 确认待上传内容共 7 个文件:
- `db_backups/add_design_report_leader_instruction_and_note_history_20260717.sql`
- `gptlog-process/gpdlog.md`
- `src/views/ProductionManagement/DeliveryNoticeList/index.vue`
- `src/views/ProductionManagement/DesignReportTask/Report/index.vue`
- `src/views/ProductionManagement/DesignReportTask/Task/index.vue`
- `src/views/ProductionManagement/WorkHoursCheck/index.vue`
- `src/views/ProductionManagement/WorkhoursEdit/index.vue`
3. 复核较早保留的三处修改:发货列表增加订单、入库、完成、合格数量;工时校验允许编辑设备和人员工时并传递加工工时;工时编辑同步设备工时输入和修改提示。
4. 复核设计报工相关修改,包括分类和任务来源、创建人编辑权限、领导批示、历史倒序、完成入口迁移、未完成默认筛选、领导及管理员权限、列表字段顺序、行高字体列宽和长文本换行。
5. 复核数据库迁移脚本共 409 行,包含任务来源字段、任务说明类型约束、领导批示权限、任务说明新增、任务查询、任务新增和任务编辑过程。
6. 执行 `git fetch origin` 刷新远程状态,确认上传前本地与远程分叉为 `0 0`,远程没有需要合并的新提交。
7. 执行工作区和暂存区差异空白检查,均通过;仅有仓库已有的 LF/CRLF 转换提示。
8. 对工作区和暂存区执行数据库密码及常见明文凭据模式扫描,均未发现明文数据库密码;此前用户提供的密码未进入提交内容。
9. 对全部 5 个变更 Vue 文件执行 ESLint设计任务、设计报工和发货列表相关检查通过两个历史工时页面存在约 1260 个原有格式错误,远超本次少量业务修改范围。
10. 为避免在上传任务中夹带上千行无关格式化,没有自动修复两个历史工时页面;最近一次 `npm run build` 已成功编译包含全部变更的项目,确认不存在模板或 JavaScript 编译错误。
11. 执行 `git add -A` 暂存当前全部修改,确认暂存区正好包含上述 7 个文件,共新增 1228 行、删除 108 行。
12. 对暂存区再次执行空白和明文凭据检查,均通过。
13. 创建功能提交:
- 提交号:`e31027a`
- 提交信息:`feat: 完善设计任务与工时维护`
- 变更统计7 个文件,新增 1228 行、删除 108 行。
14. 执行 `git push origin snapshot/local-save-20260625-154806`,功能提交成功推送,远程分支从 `5b73972` 更新到 `e31027a`
15. 功能提交推送成功后,按仓库 `AGENTS.md` 要求追加本条完整中文上传过程日志,并通过独立日志提交继续同步到同一远程分支。
### 修改文件
- `gptlog-process/gpdlog.md`
### 结论
- 当前工作区中的设计任务、设计报工、发货数量、工时编辑、数据库迁移和此前执行日志已全部创建功能提交并推送到远程分支。
- 功能提交号为 `e31027a`
- 数据库明文密码未进入提交内容。
- 本条上传过程日志将通过后续独立提交同步到远程。
### 验证结果
- 上传前本地与远程分叉为 `0 0`
- 工作区和暂存区空白检查通过。
- 工作区和暂存区明文凭据扫描通过。
- 设计任务和设计报工目标页面 ESLint 通过。
- `npm run build` 生产构建通过。
- 功能提交已成功推送到远程。
## 2026-07-20 增加设计工时报表数据查看权限
### 用户提问
- 用户要求修改 `ResearchManagement/DesignReportTask/HoursReport/index`,增加设计工时报表权限限制:普通用户的报工数据只能查看与自己有关的数据,即任务创建人是本人或者报工人是本人;角色包含“领导”或“管理员”的用户可以查看全部工时。
### 执行过程
1. 读取仓库根目录 `AGENTS.md`,确认本次执行结束后必须将提问、完整执行过程和结论以中文追加到 `gptlog-process/gpdlog.md`
2. 检查 Git 工作区,确认开始时已有 `gptlog-process/gpdlog.md` 的未提交修改;该修改属于既有用户工作,执行过程中予以保留,没有覆盖或回退。
3. 搜索页面路径和设计工时报表相关代码,确认实际页面为 `src/views/ProductionManagement/DesignReportTask/HoursReport/index.vue`,页面分别调用 `设计报工_工时报表_作业者工时_查询``设计报工_工时报表_任务工时_查询` 两个存储过程。
4. 检查报表页面、设计任务页面、设计报工页面、Vuex 用户状态和现有数据库迁移,确认当前登录人姓名来自 Vuex `name`,角色编号来自 Vuex `token`;任务创建人存储在 `MES_设计报工_任务.创建人`,报工人存储在 `MES_设计报工_记录.操作人`
5. 复核现有领导批示权限实现,确认项目通过 `登录基础数据_角色信息.Roles_number` 查找角色,并以 `Roles_Function` 是否包含“领导”或“管理员”作为特权角色判定。本次沿用相同权限口径,避免同一模块出现两套角色规则。
6. 修改工时报表页面的查询参数:在原日期、操作人、项目号、物料编码、类别和 DID 参数后增加“当前操作人”和“角色编号”,并增加 `currentUserName``currentRoleId` 两个方法读取当前登录状态。
7. 新增可重复执行的数据库迁移 `db_backups/add_design_report_hours_report_permissions_20260720.sql`,使用 `CREATE OR ALTER PROCEDURE` 更新作业者工时和任务工时两个查询过程。
8. 两个查询过程均增加 `@当前操作人``@角色编号` 参数,并在读取报工基础数据前查询当前角色是否具有查看全部权限;角色功能包含“领导”或“管理员”时放行全部记录。
9. 对普通角色增加数据库侧逐条过滤:仅当 `任务.创建人 = 当前操作人``记录.操作人 = 当前操作人` 时保留报工记录;当前操作人为空时默认返回空集,防止登录信息缺失导致意外放行。
10. 保留原“操作人”等业务筛选条件,并让权限条件与业务筛选同时生效;因此普通用户手工填写其他报工人的筛选值也不能绕过基础权限。
11. 执行目标 Vue 文件 ESLint检查通过仅输出项目既有的 Baseline 和 Browserslist 数据过期提示。
12. 执行目标文件空白差异检查,首次发现新 SQL 文件首尾各有一个多余空行;清理后重新检查通过,仅有仓库换行符转换提示。
13. 检查本机 SQL Server 工具,确认 `sqlcmd` 和 SQL Server 2019 LocalDB 可用;启动 `MSSQLLocalDB`,确认测试前不存在名为 `YL_MESDB` 的本地数据库。
14. 创建一次性隔离测试数据库和最小表结构,构造普通设计人员、研发领导、系统管理员三种角色,以及任务创建人、报工人相同和不同的五条报工数据。
15. 在 LocalDB 执行新增迁移,两个存储过程均编译成功。
16. 执行权限用例并全部通过:普通用户仅看到本人创建任务或本人报工的三条记录;普通用户按其他操作人筛选时只能看到本人创建任务内的匹配记录,不能看到无关任务;领导看到全部五条记录;管理员看到全部五条记录;普通角色登录人为空时返回空集。
17. 测试完成后删除一次性 LocalDB 测试数据库和临时测试脚本,再次查询确认测试数据库数量为 0工作区没有测试资源残留。
18. 执行 `npm run build`Webpack 生产构建成功仅有项目既有的大资源体积、Baseline 数据和 Browserslist 数据过期警告没有模板、JavaScript、样式或 SQL 相关编译错误。
19. 执行最终 Git 状态、目标差异、空白和关键权限分支检查,确认页面仅增加身份参数传递,迁移恰好包含两个过程、两组权限参数和两处数据库权限过滤;没有产生受版本控制的构建产物变化。
20. 本次未连接或修改生产数据库;交付的数据库变更为已经 LocalDB 编译和权限用例验证通过的迁移脚本。
### 修改文件
- `src/views/ProductionManagement/DesignReportTask/HoursReport/index.vue`
- `db_backups/add_design_report_hours_report_permissions_20260720.sql`
- `gptlog-process/gpdlog.md`
### 结论
- 设计工时报表的作业者工时和任务工时查询现已同时受数据库权限限制。
- 普通用户只能查看任务创建人是本人或报工人是本人的报工记录,页面上的其他筛选条件不能扩大该数据范围。
- 角色功能包含“领导”或“管理员”的用户可以查看全部设计工时。
- 登录人信息为空且角色不具备查看全部权限时默认不返回数据。
- 生产数据库尚未执行本次迁移,需要在目标环境发布 `db_backups/add_design_report_hours_report_permissions_20260720.sql` 后,新前端查询参数才能与存储过程签名一致。
### 验证结果
- 目标 Vue 文件 ESLint 通过。
- 目标差异空白检查通过。
- LocalDB 中两个存储过程编译通过。
- 普通用户本人相关数据权限验证通过。
- 普通用户筛选不可越权验证通过。
- 领导查看全部工时验证通过。
- 管理员查看全部工时验证通过。
- 空登录人默认拒绝验证通过。
- LocalDB 测试数据库和临时脚本已清理。
- `npm run build` 生产构建通过。
## 2026-07-20 发布设计工时报表权限到生产数据库
### 用户提问
- 用户提供生产数据库 `192.168.2.92``sa` 账号凭据,用于发布上一轮已经完成并验证的设计工时报表权限迁移。
- 数据库密码仅用于当前命令进程,未在本日志中记录明文。
### 执行过程
1. 将本次操作范围限定为把 `db_backups/add_design_report_hours_report_permissions_20260720.sql` 发布到 `192.168.2.92 / YL_MESDB`,不修改其他数据库对象或业务数据。
2. 使用临时进程环境变量向 `sqlcmd` 提供密码;命令结束后立即清除环境变量,没有创建凭据文件,也没有把密码写入仓库脚本或执行日志。
3. 发布前执行只读连接和环境检查,确认目标数据库为 `YL_MESDB`、服务器名为 `YLLT-MES`,服务器时间为 `2026-07-20 09:04:07`
4. 检查两个目标存储过程,确认发布前均存在:任务工时查询过程修改时间为 `2026-07-15 18:14:19`,作业者工时查询过程修改时间为 `2026-07-10 17:39:34`
5. 检查依赖结构,确认 `MES_设计报工_任务.创建人``MES_设计报工_记录.操作人``登录基础数据_角色信息.Roles_Function` 均存在,字段长度和迁移定义兼容。
6. 使用 `sqlcmd -b -f 65001` 执行权限迁移;数据库成功切换到 `YL_MESDB`,两个 `CREATE OR ALTER PROCEDURE` 均执行成功,没有 SQL 错误或回滚。
7. 发布后检查过程元数据,确认两个过程修改时间均更新为 `2026-07-20 09:04:21`,各有 9 个参数,并且 `@当前操作人``@角色编号` 参数各存在一次。
8. 首轮使用 SQL `LIKE` 检查过程定义时,由于方括号被解释为模式字符而返回错误的 0该结果只影响检查表达式不影响已发布过程。随后改用 `CHARINDEX` 精确检查,没有重复发布或修改数据。
9. 精确检查确认两个过程均包含三类权限规则:角色功能包含“领导”或“管理员”时查看全部;普通用户按任务创建人或报工人匹配;当前登录人为空时默认拒绝。
10. 查询角色数据的汇总数量,确认生产环境中包含“领导”的角色有 3 个,包含“管理员”的角色有 3 个。
11. 使用不存在的 DID 和验证身份参数分别调用两个过程,确认新增参数签名可正常接收,过程执行无错误且不返回业务数据。
12. 创建一次性只读生产验证脚本,不包含数据库凭据;脚本自动选取一个普通角色、一名已有报工人员、一个领导角色和一个管理员角色,并以临时表接收两个过程结果。
13. 普通用户对账:基础表按“任务创建人是本人或报工人是本人”计算的记录数,与作业者工时报表三级明细数一致。
14. 领导对账:作业者工时报表三级明细数与全部已结束报工记录数一致。
15. 管理员对账:任务工时报表一级汇总的报工次数与全部已结束报工记录数一致。
16. 生产数据对账结果为:全部已结束报工 12 条,抽样普通用户可见 3 条,普通用户、领导和管理员三类对账均通过。
17. 删除一次性生产验证脚本,确认其没有留在工作区;整个验证过程仅执行查询、临时表和存储过程调用,没有写入或修改生产业务表。
18. 按仓库 `AGENTS.md` 要求追加本条完整中文执行过程日志,日志不包含明文数据库密码。
### 修改文件
- `gptlog-process/gpdlog.md`
### 结论
- 设计工时报表权限迁移已成功发布到 `192.168.2.92 / YL_MESDB`
- 两个生产存储过程现已支持当前登录人和角色编号参数,并执行普通用户本人数据限制以及领导、管理员查看全部规则。
- 生产实际数据对账通过:普通用户只能看到本人相关数据,领导和管理员可以看到全部工时。
- 本次没有修改生产业务数据,数据库密码没有写入仓库或日志。
### 验证结果
- 生产数据库连接和依赖结构检查通过。
- 两个过程发布成功,修改时间和参数检查通过。
- 两个过程权限定义精确检查通过。
- 普通用户生产数据权限对账通过:抽样可见 3 条。
- 领导生产数据权限对账通过:可见全部 12 条。
- 管理员生产数据权限对账通过:可见全部 12 条。
- 临时验证脚本已清理。
## 2026-07-20 修复设计任务指派对象多选只显示一个值
### 用户提问
- 用户要求修改 `ResearchManagement/DesignReportTask/Task/index` 的“指派对象”,当前多选后只显示一个值,多选时应显示多个指派对象。
### 执行过程
1. 检查实际页面 `src/views/ProductionManagement/DesignReportTask/Task/index.vue` 的列表列、Element UI 多选控件、编辑回填、人员远程查询、选择变化处理和保存参数。
2. 确认控件已经配置 `multiple`,数据库字段也支持逗号分隔的多个 ID 和姓名;问题不是控件缺少多选配置。
3. 定位根因:`queryPersonnel` 每次远程搜索都会用本次结果整批替换 `personnelOptions`,导致之前已选人员从候选集合消失;`handleAssigneeChange` 又只从当前候选集合查找姓名,因此 ID 数组可包含多人,但保存的 `指派对象` 姓名只剩当前搜索结果中的一人。
4. 使用上一轮用户提供的生产数据库账号执行只读汇总,未记录明文密码。生产库共有 31 个设计任务,其中 14 个任务的 `指派对象ID` 包含多个值,而这 14 个任务的 `指派对象` 姓名都只有一个值,验证了代码分析。
5. 检查人员查询过程,确认默认最多返回 200 人;生产环境当前有 134 名有效人员,所有任务中已保存的指派对象 ID 均能在有效人员视图中找到,因此可以通过 ID 映射即时还原完整姓名。
6. 一次尝试通过 `INSERT EXEC 设计报工_人员查询` 统计默认结果时,因该过程内部本身使用 `INSERT EXEC` 而触发 SQL Server“不允许嵌套 INSERT EXEC”该只读尝试没有写入或修改数据。随后改为直接查询人员权限视图成功得到有效人员和 ID 覆盖结果。
7. 修改任务列表“指派对象”列,使用自定义模板和 `formatAssigneeNames`,优先按 `指派对象ID` 从人员姓名缓存逐个解析并用顿号连接;即使历史数据库姓名字段只有一个值,页面也能显示全部 ID 对应的人员。
8. 增加统一的人员 ID 标准化,编辑回填时把字符串和数字 ID 统一转换为去除空格的字符串,避免严格比较时因类型不同丢失已选项。
9. 增加人员姓名缓存,人员查询每次返回后都把 ID 和姓名合并到缓存;缓存独立于当前下拉筛选结果,因此列表显示不会随着远程搜索切换而丢失姓名映射。
10. 增加 `mergePersonnelOptions`:远程搜索刷新候选项时保留所有当前已选人员,再加入本次搜索结果;连续搜索并选择不同人员时,前一次选择的标签和姓名不会丢失。
11. 修改 `handleAssigneeChange`,按多选值的实际选择顺序保存全部人员 ID 和全部人员姓名,不再按当前候选数组过滤或重排。
12. 同步复用相同逻辑修正“对其可见”多选,避免同一页面的另一个人员多选控件存在相同的数据截断问题。
13. 新建和编辑对话框打开时重新加载完整指派人员与可见人员选项;编辑历史任务时先保留已有选项,再由最新人员查询结果覆盖错误或缺失标签。
14. 为两个人员远程查询增加请求序号,较早请求晚返回时会被忽略,避免快速输入过程中旧结果覆盖新结果。
15. 调整查询异常分支,网络或接口查询失败时只保留当前已选人员,不再清空整个候选集合,确保已选标签保持显示。
16. 首次运行组件真实方法测试时PowerShell 管道编码将测试脚本中的中文属性名替换成问号Node 在载入前报语法错误;该问题仅发生在临时测试命令,没有修改代码或数据。随后使用 Unicode 转义重新执行。
17. 从目标 Vue 文件动态加载真实组件方法并验证六个场景,全部通过:连续远程搜索保留前次选择、保存全部 ID、按选择顺序保存全部姓名、历史单姓名数据按 ID 显示多人、人员 ID 类型统一、查询失败保留已选项。
18. 执行目标 Vue 文件 ESLint检查通过仅输出项目既有的 Baseline 和 Browserslist 数据过期提示。
19. 执行 `npm run build`Webpack 生产构建成功仅有项目既有的大资源体积、Baseline 数据和 Browserslist 数据过期警告没有模板、JavaScript 或样式编译错误。
20. 检查现有开发服务器,确认端口 1997 的进程为当前仓库的 webpack dev server访问 `https://localhost:1997/` 返回 HTTP 200无需重复启动服务器。
21. 执行最终 Git 状态、空白差异和明文数据库密码检查;目标变更没有空白错误、没有受版本控制的构建产物变化,也没有包含明文数据库密码。
22. 本次只修改前端显示和多选数据处理,没有更新生产数据库业务记录;现有 14 条多 ID、单姓名任务会由页面根据 ID 映射立即显示完整人员,后续重新选择并保存时会写入完整姓名。
### 修改文件
- `src/views/ProductionManagement/DesignReportTask/Task/index.vue`
- `gptlog-process/gpdlog.md`
### 结论
- “指派对象”现在支持连续远程搜索并保留多个已选人员,选择和保存均包含全部 ID 与姓名。
- 设计任务列表会根据全部指派对象 ID 显示对应人员,历史上姓名字段只保存一个值的任务也能显示完整多人。
- “对其可见”人员多选同步采用相同的保留和拼接逻辑。
- 生产业务数据未被改写。
### 验证结果
- 生产只读诊断确认 14 个多 ID 任务此前均只有一个姓名。
- 生产 134 名有效人员覆盖全部已保存指派对象 ID。
- 六项组件多选和显示方法测试通过。
- 目标 Vue 文件 ESLint 通过。
- 目标差异空白检查通过。
- `npm run build` 生产构建通过。
- `https://localhost:1997/` 返回 HTTP 200。
- 开发服务器当前 `app.js` 已包含 `formatAssigneeNames` 修复代码,确认热更新后的页面资源已生效。
- 变更文件明文数据库密码检查通过。
## 2026-07-20 机加正在加工任务在排产日程显示绿色
### 用户提问
- 用户要求修改 `PlanManagement/SelfMakePlandone/index``PlanManagement/WorkstationPlan/index` 两个页面的日程页签:机加正在加工的任务需要显示为绿色,正在加工数据来源为 `设备管理_设备状态_查询`
### 执行过程
1. 检查两个目标 Vue 文件的模板、FullCalendar 配置、日程事件计算属性、页签监听、任务查询刷新和现有颜色规则。
2. 确认两个页面的日程事件此前只按优先级着色:加急任务为红色 `#f56c6c`,普通任务为蓝色 `#409EFF`,没有读取实时设备状态。
3. 搜索仓库内设备状态调用和技术资料,确认实际过程名为 `设备管理_设备状态_查询`,参数为 `@设备名称`;现有设备状态页面以空设备名称查询全部设备。
4. 使用生产数据库执行只读检查,确认过程当前返回 `TaskAID`、加工状态编号和加工状态文本,并只包含加工状态 2 或 4状态 2 为“辅助开始”,状态 4 为“开始加工”。
5. 复核两个排产页面,确认任务行在派工、分组等操作中使用 `row.taskaid` 作为 `TaskAID`,可与设备状态过程返回的 `TaskAID` 精确关联;同时兼容返回字段大小写差异和 `AID` 备用字段。
6. 查询生产排产过程定义,确认页面默认 `已完成` 表示排产状态为 1而不是加工任务已经结束当前设备状态任务仍属于页面默认“已排产、自制件”数据范围。
7. 生产只读统计确认当前共有 18 个机加正在加工任务,其中辅助开始 3 个、开始加工 15 个18 个 TaskAID 均唯一且全部位于两个页面默认日程范围。
8. 在两个页面的数据状态中增加 `machiningTaskIds`,用于保存设备状态过程返回并标准化、去重后的当前加工任务 ID。
9. 增加 `normalizeTaskAid``getTaskAid`,把数字或字符串任务主键统一转为去除空格的字符串,并兼容 `taskaid``TaskAID``AID` 三种字段名。
10. 增加 `loadMachiningTaskIds`,使用 `CreateData('11', '设备管理_设备状态_查询', [['设备名称', '']])` 查询全部设备状态;查询失败时保留原有状态并记录控制台错误,不阻塞排产任务列表。
11. 增加统一的 `getCalendarEventStyle` 颜色规则:正在加工任务使用绿色 `#67c23a``machining-event` 类;非加工中的加急任务保持红色;其他普通任务保持蓝色。正在加工绿色优先于加急红色。
12. 将两个页面的普通日程和已排产日程事件都改为使用统一颜色规则,背景色与边框色一致,文字保持白色。
13. 在进入日程页签时重新查询设备状态;在执行日程任务查询时同步刷新设备状态,保证查询后的任务颜色基于最新设备数据。
14. 增加 `machiningTaskIds` 监听和 `refreshVisibleCalendarEvents`,设备状态异步返回后立即更新当前可见日历事件并调用 FullCalendar `refetchEvents`,避免必须再次切换页签才能看到绿色。
15. 从两个目标 Vue 文件动态加载真实组件方法,分别验证 7 个场景全部通过加工中覆盖加急显示绿色、非加工加急保持红色、普通保持蓝色、TaskAID 字段变体匹配、调用指定设备状态过程、查询全部设备、活动任务 ID 标准化去重。
16. 首次执行完整 ESLint两个历史页面分别存在数百条原有缩进、分号、引号和尾随空格问题检查被既有问题阻断没有对整页执行自动格式化避免产生上千行无关改动。
17. 按 Git 新增行精确过滤 ESLint 结果,首次发现两个页面各一处本次事件 `classNames` 尾随逗号错误;删除后重新检查,两页本次各 53 行新增代码的 ESLint 消息均为 0。
18. 执行 `npm run build`Webpack 生产构建成功仅有项目既有的大资源体积、Baseline 数据和 Browserslist 数据过期警告,没有模板或 JavaScript 编译错误。
19. 检查现有 webpack 开发服务器,`https://localhost:1997/` 返回 HTTP 200读取热更新后的 `app.js`,确认包含设备状态过程名、`machiningTaskIds``machining-event` 规则。
20. 执行最终 Git 状态、空白差异和明文密码检查;没有空白错误,没有受版本控制的构建产物变化,变更中没有明文数据库密码。
21. 本次生产数据库检查均为只读查询,没有创建、更新或删除数据库对象及业务数据;页面通过现有设备状态过程实时取数,不需要新增数据库迁移。
### 修改文件
- `src/views/PlanManagement/SelfMakePlandone/index.vue`
- `src/views/PlanManagement/WorkstationPlan/index.vue`
- `gptlog-process/gpdlog.md`
### 结论
- 两个排产页面的日程页签现在都会从 `设备管理_设备状态_查询` 获取机加正在加工任务。
- 日程任务通过 TaskAID 与设备状态结果关联,辅助开始和开始加工中的任务显示绿色。
- 颜色优先级为正在加工绿色、加急红色、普通蓝色。
- 进入日程页签、点击查询以及设备状态异步返回时都会刷新日历颜色。
- 本次没有修改生产数据库业务数据。
### 验证结果
- 生产设备状态过程和 TaskAID 字段检查通过。
- 生产当前 18 个机加正在加工任务全部位于默认日程范围。
- 两页共 14 项真实组件方法测试通过。
- 两页本次新增行 ESLint 消息均为 0。
- `npm run build` 生产构建通过。
- `https://localhost:1997/` 返回 HTTP 200。
- 开发服务器当前 bundle 已包含绿色事件和设备状态查询代码。
- 目标差异空白检查通过。
- 变更文件明文数据库密码检查通过。
## 2026-07-20 审查发货通知列表两部分数据合并
### 用户提问
- 用户要求查看 `ProductionManagement/DeliveryNoticeList/index` 页面的数据是否有问题,并说明当前数据由两部分构成:一部分来自 `[SAP].[SBO_YL].[dbo].[UBT_ODRF_ODLNMES]` 视图,另一部分来自手工编辑为优先的任务。
### 执行过程
1. 按只读审查处理本次请求,检查目标页面模板、查询参数、数据加载、数量字段、日期字段和状态格式化;除仓库要求的执行日志外,不修改页面或业务逻辑。
2. 确认前端只调用 `装配中心任务看板_发货状态查询`,页面自身没有合并两份数据;两部分数据的构成和优先规则全部位于生产存储过程中。
3. 检查仓库迁移 `db_backups/update_delivery_notice_list_proc_20260626.sql`,发现其仍为早期单分支版本,不能代表当前生产逻辑;随后使用用户此前提供的生产数据库账号执行只读核查,密码未写入仓库或日志。
4. 读取生产过程元数据,确认 `装配中心任务看板_发货状态查询` 修改时间为 `2026-07-17 10:20:40`,依赖 SAP 发货视图、MES 生产订单视图、加工操作记录、质量检验记录、生产工时和人员信息。
5. 读取生产过程完整定义,确认当前确实由两个 `UNION ALL` 分支组成:
- 第一分支以 `[SAP].[SBO_YL].[dbo].[UBT_ODRF_ODLNMES]` 为主,按生产单号左连 MES 生产订单。
- 第二分支读取 `View_生产订单_MES.优先级='是'` 的装配任务,并排除已经存在于 SAP 视图的生产订单。
6. 确认“手工编辑为优先”并不是独立表,而是 MES 生产订单任务的 `优先级` 字段;第二分支的 SAP 字段为空,最终按 `要求发货时间` 升序排列时,这些空日期手工任务会排在前面。
7. 通过结果集元数据核对前端字段,确认过程返回 42 个字段,其中包含 `检验数量`,但不包含页面使用的 `合格数量`;因此页面“合格数量”列当前没有后端数据来源,会显示为空。
8. 创建会话级临时表接收生产过程默认结果仅进行只读统计。首次稳定快照显示SAP 源 11 行,手工优先源 4 个任务,两个来源的逻辑基数合计应为 15过程实际返回 20 行。
9. 分析 5 条额外结果确认全部来自操作记录的一对多联表SAP 生产订单 7517 对应 5 个不同操作人,被拆成 5 行,额外产生 4 行;手工优先订单 8169 对应 2 个不同操作人,被拆成 2 行,额外产生 1 行。
10. 检查 SAP 与 MES 订单关联,当前没有一个 SAP 订单匹配多个 MES TaskAID重复不是生产订单关联到多任务造成而是 `YL_加工中心_操作记录表``b.操作人` 分组造成。
11. 检查质检联表,发现任务 18081 同时有 4 条操作记录和 4 条质检记录,当前过程先直接联表再聚合,形成 16 行笛卡尔乘积;正确检验数量为 10过程聚合为 40。生产结果中有 5 行检验数量与独立质检汇总不一致。
12. 核对质检视图字段,确认同时存在 `检验数量``合格数``不合格数`。当前过程汇总的是 `检验数量`,不仅字段名与页面的 `合格数量` 不一致,业务口径也不是“合格数”。
13. 检查 SAP 视图当前数据11 行组合键均不同,但有 2 行生产单号为空,且有 2 行找不到对应 MES 生产订单;这些行在过程里保留 SAP 的 `生产单号``要求发货时间`,但页面展示的是 MES 的 `订单编号``要求发货日期`,导致页面生产订单和发货日期为空。
14. 默认结果统计发现 7 行页面使用的 `要求发货日期` 为空,其中包含 SAP 无 MES 匹配行以及手工优先行;另有 1 行 SAP `要求发货时间` 与 MES `要求发货日期` 日期不一致。查询筛选和排序依据 SAP 日期,页面却显示 MES 日期,存在“按一个日期查、展示另一个日期”的口径偏差。
15. 检查手工优先分支的筛选条件,确认代码明确没有应用 `@齐套``@发料状态``@要求发货日期`。生产调用验证结果:
- 选择“齐套=否”时,手工分支返回 5 行5 行实际均为齐套,全部违反筛选条件。
- 选择“发料状态=未发料”时,手工分支返回 5 行5 行实际均已发料,全部违反筛选条件。
- 选择不存在的日期 `2099-01-01` 时仍返回 5 行手工结果5 行全部不符合日期条件。
16. 检查页面发料状态格式化,确认未发料、空值或 0 都被格式化为空字符串,而页面筛选项名称是“未发料”;默认结果快照中有 10 行发料状态显示为空,用户无法从列表直接看出“未发料”。
17. 检查数量显示SAP 分支返回 `交货数量`,当前默认结果中 15 条展开结果具有交货数量,但页面在上一轮改为订单数量、入库数量、完成数量、合格数量后不再展示 `交货数量`SAP 数据源的核心交货数量因此不可见。
18. 检查任务状态,默认结果中任务状态为 0 的 6 行、2 的 1 行、4 的 11 行、无 MES 任务的 2 行;页面以“任务状态大于 0”统一显示“已开工”。按系统现有状态语义状态 4 是已完成,但在“装配开工”列显示已开工属于简化口径,需确认是否符合业务期望。
19. 一次补充只读汇总因使用未加方括号的 `RowCount` 别名触发 SQL 语法错误;该语句未修改数据。将别名改为 `[RowCount]` 后重新执行成功。
20. 由于 SAP 同步和 MES 操作记录实时变化,核查期间个别分支行数短暂波动;最终在 `2026-07-20 09:58:33` 重新取稳定快照,确认 SAP 源 11 行、手工优先源 4 个任务、过程结果 20 行,核心重复结论不变。
21. 本次所有生产数据库操作均为对象定义读取、临时表和 SELECT 查询,没有创建、更新或删除生产数据库对象及业务数据。
22. 按仓库 `AGENTS.md` 要求追加本条完整中文审查日志,日志不包含明文数据库密码。
### 修改文件
- `gptlog-process/gpdlog.md`
### 结论
- 当前生产过程的数据来源结构与用户描述一致SAP 发货视图加上 SAP 中不存在的手工优先装配任务。
- 当前数据结果存在明确问题操作人联表造成重复行操作记录与质检记录形成乘积并放大检验数量页面“合格数量”字段无对应返回值SAP 与 MES 日期和订单字段混用,手工优先分支绕过三个页面筛选条件。
- 当前逻辑基数应为 15过程返回 20额外 5 行均已定位到具体联表原因。
- 页面还隐藏了 SAP 交货数量,并把未发料显示为空;这些属于展示口径问题,需要结合业务期望决定是否恢复或调整。
- 本次只完成诊断,没有修改页面、存储过程或生产业务数据。
### 验证结果
- 生产过程定义和依赖检查完成。
- 两部分数据源结构检查完成。
- SAP 源、手工优先源和最终结果基数对账完成。
- 重复行来源定位完成。
- 质检数量乘积放大验证完成。
- 前后端字段映射检查完成。
- 齐套、发料状态和要求发货日期筛选穿透验证完成。
- SAP/MES 订单和日期缺失、错配检查完成。
- 本次未修改生产业务数据。
- 变更日志未包含明文数据库密码。
## 2026-07-20 修复发货通知列表重复、合格数量和双来源字段
### 用户提问
- 用户确认需要修复上一轮发货通知列表审查中发现的问题:结果重复、页面合格数量无数据、质检数量因联表乘积被放大,以及 SAP/MES 双来源的订单和日期显示。
- 用户进一步明确双来源口径SAP 数据使用 SAP `要求发货时间`,手工编辑为优先的 MES 数据使用 MES `要求发货日期`;销售订单取项目号或合同号,理论上不应为空,当前页面有两行为空需要修复。
### 执行过程
1. 将修复范围限定为用户本轮明确列出的四类问题,不修改上一轮审查中另外提出但用户本轮未要求的交货数量展示和未发料文本等口径。
2. 复核前端调用,确认 `装配中心任务看板_发货状态查询` 仅被 `DeliveryNoticeList/index.vue` 使用;页面已经读取 `合格数量` 和统一的 `要求发货日期`,本轮只需修复数据库过程返回口径,不需要修改 Vue 页面。
3. 使用生产数据库执行只读核查,确认两条销售订单为空的数据均来自 SAP 视图中没有生产单号、无法匹配 MES 任务的行;两条 SAP 数据的 `项目号` 均不为空,分别可作为页面销售订单/合同号的回填值。
4. 设计新的过程结构,先分别构造三个聚合集合再连接主数据:
- 操作人先按 `TaskAID + 操作人` 去重,再按 TaskAID 使用 `STRING_AGG` 合并为一个逗号分隔字段。
- 质检记录先按 TaskAID 汇总 `合格数``合格数量`
- 装配工时先按合同号汇总,保持原有合同装配工时口径。
5. 通过预聚合消除原过程的两个一对多直接联表,避免不同操作人拆成多行,也避免操作记录和质检记录形成笛卡尔乘积。
6. 调整 SAP 分支的统一页面字段:
- 页面生产订单返回 `COALESCE(MES订单编号, SAP生产单号)`
- 页面销售订单返回 `COALESCE(MES合同号, SAP项目号)`
- 页面要求发货日期固定返回 SAP `要求发货时间`
- 销售订单筛选同步使用 MES 合同号或 SAP 项目号的合并值。
7. 保持手工优先分支的数据来源:生产订单和销售订单分别使用 MES 订单编号、MES 合同号,页面要求发货日期使用 MES `要求发货日期`
8. 为手工优先分支补充要求发货日期筛选,确保同一个页面日期条件在 SAP 分支按 SAP 日期、在 MES 分支按 MES 日期生效。
9. 将最终排序改为统一页面字段 `要求发货日期`,然后按订单编号和物料编号排序;两部分数据分别按各自正确日期参与排序。
10. 将结果集最后一个字段从原 `检验数量` 改为 `合格数量`,值取质检视图 `合格数` 的 TaskAID 汇总,与页面字段名和业务口径一致。
11. 新增可重复执行的数据库迁移 `db_backups/fix_delivery_notice_list_data_merge_20260720.sql`,使用 `CREATE OR ALTER PROCEDURE` 发布修复。
12. 发布前创建一次性 SQLCMD 验证脚本,在生产连接中开启事务、临时执行新过程并完成验证后回滚;如果验证中途失败,`XACT_ABORT` 和连接断开也会回滚事务,预演不留下数据库变更。
13. 事务预演结果:新过程编译成功,返回 15 行,正好等于 SAP 11 行加手工优先 4 个任务;不再有额外重复行。
14. 事务预演确认所有结果销售订单均非空,两条原空值已经由 SAP 项目号回填。
15. 事务预演确认所有 SAP 结果的页面 `要求发货日期` 与 SAP `要求发货时间` 一致,手工优先结果保留 MES 要求发货日期;查询不存在的日期 `2099-01-01` 返回 0 行。
16. 事务预演确认所有 TaskAID 的 `合格数量` 与质检视图独立汇总的 `合格数` 一致,原任务 18081 的联表乘积放大问题被消除。
17. 事务预演全部通过并回滚后,使用用户此前提供的生产数据库账号正式执行迁移;密码仅通过当前进程环境变量使用,命令结束后清除,没有写入仓库、迁移或日志。
18. 正式发布后把验证脚本调整为只读检查已发布过程,并再次执行完整验证;结果仍为 SAP 11 行、手工优先 4 行、过程共 15 行,重复修复、销售订单回填、日期来源和合格数量全部通过。
19. 发布后检查过程元数据,确认生产过程修改时间为 `2026-07-20 10:10:50`;结果集包含一个 `合格数量` 字段,不再包含旧的 `检验数量` 字段。
20. 删除一次性事务预演和发布后验证脚本,确认临时脚本没有留在工作区。
21. 本次没有更新生产业务表数据;修复仅重建查询过程,页面下次查询会直接使用新结果。
22. 按仓库 `AGENTS.md` 要求追加本条完整中文执行日志,日志不包含明文数据库密码。
### 修改文件
- `db_backups/fix_delivery_notice_list_data_merge_20260720.sql`
- `gptlog-process/gpdlog.md`
### 结论
- 发货通知列表查询过程已完成双来源修复并发布生产数据库。
- SAP 11 行与手工优先 4 个任务现在准确返回 15 行,不再因多个操作人产生 5 条额外记录。
- 操作人改为单行合并显示,质检合格数先汇总后关联,不再发生操作记录与质检记录的乘积放大。
- 页面“合格数量”现有正确的后端字段和数据来源。
- SAP 数据显示 SAP 要求发货时间,手工优先数据显示 MES 要求发货日期,日期筛选和排序使用同一统一输出字段。
- 两条原销售订单空值已由 SAP 项目号回填,当前结果销售订单无空值。
- 本次未修改生产业务数据。
### 验证结果
- 新过程生产事务预演和回滚通过。
- 正式生产迁移发布成功。
- 发布后两个来源逻辑行数验证通过SAP 11、手工优先 4、合计 15。
- 发布后重复记录检查通过。
- 发布后销售订单非空检查通过。
- 发布后 SAP/MES 日期来源检查通过。
- 发布后未来日期筛选检查通过。
- 发布后合格数量独立汇总对账通过。
- 生产过程结果字段检查通过:有 `合格数量`,无旧 `检验数量`
- 临时验证脚本已清理。
- 日志未包含明文数据库密码。
## 2026-07-20 发货通知操作人仅显示当前加工人员
### 用户提问
- 用户要求发货通知列表的“操作人”只取当前正在加工的人;同一个任务有多人正在加工时拼接显示。
- 用户指定判定逻辑的数据来源参考 `MES_人员工时记录_获取进行中任务2`,但明确要求发货查询由一个存储过程直接输出,不复用或调用该过程。
### 执行过程
1. 搜索仓库中 `MES_人员工时记录_获取进行中任务2` 的调用位置和技术资料,确认该过程用于装配中心和质量中心查询全部未结束装配任务。
2. 使用生产数据库只读查询过程元数据和完整定义,确认该过程参数为 `@用户ID nvarchar(50)`,但当前定义实际没有使用该参数过滤数据。
3. 提取生产过程的“当前正在加工”四项真实条件:
- `操作类别 = '开始加工'`
- `结束时间 IS NULL`
- `工位名称 LIKE '%装配%'`
- `操作数值 IS NOT NULL`
4. 确认原发货查询上一轮修复后虽然已按 TaskAID 合并操作人,但其数据范围仍包含所有历史操作记录,不符合“只显示当前正在加工人员”的新要求。
5. 新建独立前向迁移 `db_backups/fix_delivery_notice_list_current_operators_20260720.sql`;迁移完整定义 `装配中心任务看板_发货状态查询`,没有修改或依赖原 `MES_人员工时记录_获取进行中任务2`
6. 在发货查询内部增加 `当前加工操作人去重` CTE直接读取 `YL_加工中心_操作记录表` 并应用上述四项条件,同时排除空操作人姓名。
7. 在去重 CTE 中按 `TaskAID + 操作人` 使用 `DISTINCT`,避免同一人员对同一任务存在重复未结束记录时重复显示姓名。
8. 增加 `当前加工操作人汇总` CTE按 TaskAID 使用 `STRING_AGG` 和姓名排序拼接所有当前加工人员;一个人显示一个姓名,多人以逗号连接。
9. SAP 分支和手工优先分支均只关联该当前加工人员汇总,不再关联历史操作人集合;其他上一轮已经修复的行数、销售订单、日期和合格数量逻辑保持不变。
10. 对新增迁移执行空白检查,首次发现文件末尾多一空行;清理后检查通过,仅有仓库换行符转换提示。
11. 创建一次性 SQLCMD 事务预演脚本,在生产连接中开始事务、临时执行新过程、完成结果验证后回滚,预演不留下生产数据库变更。
12. 事务预演确认发货查询仍返回 15 行,没有因操作人范围变化重新产生重复数据。
13. 事务预演使用独立 CTE按相同四项条件重新汇总当前加工人员并逐 TaskAID 与发货结果操作人对账,差异数量为 0。
14. 事务预演检查过程定义,确认不包含文本 `MES_人员工时记录_获取进行中任务2`,没有通过 `EXEC``INSERT EXEC` 或其他方式复用原过程。
15. 事务预演快照中,当前 15 个发货结果任务没有满足四项条件的未结束装配加工记录,因此有当前加工人员的任务数为 0、多人同时加工任务数为 0页面操作人为空符合当前实际状态。
16. 事务预演通过并回滚后,使用用户此前提供的生产数据库账号正式执行新迁移;密码仅通过当前进程环境变量使用,命令结束后清除,未写入仓库、迁移或日志。
17. 正式发布后把验证脚本调整为只读检查已发布过程,再次验证发货结果行数、当前加工人员逐 TaskAID 对账和未复用原过程,全部通过。
18. 发布后精确检查过程定义,确认开始加工、未结束、装配工位、操作数值非空四项条件均存在,原进行中任务过程名称不存在。
19. 发布后生产过程修改时间为 `2026-07-20 10:16:13`
20. 删除一次性事务预演和发布后验证脚本,确认没有临时验证资源残留。
21. 本次没有更新生产业务表数据,也没有修改 `MES_人员工时记录_获取进行中任务2`;仅重建发货状态查询过程。
22. 按仓库 `AGENTS.md` 要求追加本条完整中文执行日志,日志不包含明文数据库密码。
### 修改文件
- `db_backups/fix_delivery_notice_list_current_operators_20260720.sql`
- `gptlog-process/gpdlog.md`
### 结论
- 发货通知列表操作人现在只显示满足“开始加工、未结束、装配工位、操作数值非空”的当前加工人员。
- 同一 TaskAID 的当前加工人员先按姓名去重,再按姓名排序并以逗号拼接。
- 发货查询直接读取操作记录表并一次性输出全部页面数据,没有调用或复用 `MES_人员工时记录_获取进行中任务2`
- 上一轮修复的 SAP 11 行加手工优先 4 行、销售订单、双来源日期和合格数量口径保持不变。
- 当前生产快照没有发货任务正在装配加工,操作人暂时为空属于正确结果;后续产生未结束加工记录后会自动显示对应人员。
- 本次未修改生产业务数据和原进行中任务过程。
### 验证结果
- 新过程生产事务预演和回滚通过。
- 正式生产迁移发布成功。
- 发货结果行数保持 15 行。
- 当前加工人员独立汇总逐 TaskAID 对账通过。
- 四项当前加工条件定义检查通过。
- 多人拼接 SQL 结构检查通过。
- 未复用 `MES_人员工时记录_获取进行中任务2` 检查通过。
- 生产过程修改时间检查通过。
- 临时验证脚本已清理。
- 日志未包含明文数据库密码。
## 2026-07-20 发货通知合格数量改为终检口径
### 用户提问
- 用户指出生产订单 8169 的订单数量只有 16但发货通知列表显示合格数量 32要求核查并修复。
### 执行过程
1. 查询生产数据库中订单 8169 对应的装配任务,确认 TaskAID 为 23552计划数量、完成数量和入库数量均为 16。
2. 查询该 TaskAID 的原始质检记录,确认不是视图重复行:同一任务分别存在收检 16 合格和终检 16 合格两条记录。
3. 检查已发布的 `装配中心任务看板_发货状态查询`,定位到 `质检汇总` 对全部质检类型直接执行 `SUM(合格数)`,因此把收检和终检相加为 32。
4. 搜索仓库现有生产关闭、齐套跟踪和终检页面逻辑,确认生产完工及发货相关合格数量统一使用 `质检类型 = '终检'`;终检页面对应检测类型编号为 8。
5. 对当前发货来源任务按质检类型批量对账,发现 6403、7517、8168、8169 均同时存在收检与终检,原口径分别产生 10、100、16、32 的翻倍结果。
6. 按终检口径重新汇总后,上述订单合格数量分别为 5、50、8、16均未超过各自计划数量未采用按计划数量强制截断的方式避免掩盖真实数据异常。
7. 修改 `db_backups/fix_delivery_notice_list_current_operators_20260720.sql` 中的 `质检汇总`,增加 `WHERE 质检类型 = N'终检'`SAP 与手工优先两个分支继续共用同一个按 TaskAID 汇总后的结果。
8. 创建一次性 SQLCMD 事务预演脚本,在生产连接中临时重建过程并查询 8169。首次预演的过程执行成功但定义断言使用 `LIKE` 时方括号被解释为模式字符,断言主动报错;连接关闭后未提交事务自动回滚,生产过程没有发生变更。
9. 将断言改为 `CHARINDEX` 精确字符串检查后重新预演确认过程定义已限定终检8169 返回计划数量 16、合格数量 16随后正常回滚事务。
10. 使用同一迁移脚本正式更新生产数据库,仅修改查询存储过程,没有更新任何生产业务表数据。
11. 发布后调用完整发货查询并按当前来源动态对账。当前实时数据已从早先快照的 SAP 11 行变为 10 行,手工优先仍为 4 行,理论总数 14过程实际返回 14说明行数变化来自 SAP 实时源,而非本次口径修改丢行。
12. 发布后确认 8169 合格数量为 16、8168 为 8、6403 为 57517 已不在当前 SAP 发货源中,因此不再出现在页面结果。
13. 检查生产过程定义,确认终检限制存在,正式发布时间为 `2026-07-20 10:22:10`
14. 删除一次性事务预演脚本,确认仓库没有遗留临时验证文件。
15. 按仓库 `AGENTS.md` 要求追加本条完整中文执行日志,日志不包含明文数据库密码。
### 修改文件
- `db_backups/fix_delivery_notice_list_current_operators_20260720.sql`
- `gptlog-process/gpdlog.md`
### 结论
- 8169 显示 32 的原因是同一任务的收检 16 与终检 16 被错误相加,并非订单实际有 32 件合格品。
- 发货通知列表的“合格数量”现已只汇总终检合格数8169 正确显示为 16。
- 同类翻倍问题已一并修复,没有针对单个订单写特殊逻辑,也没有使用计划数量截断结果。
- 本次仅更新发货查询存储过程,未修改生产业务数据。
### 验证结果
- 生产事务预演及回滚通过。
- 正式生产迁移发布成功。
- 8169 计划数量 16、合格数量 16。
- 当前 SAP 10 行加手工优先 4 行,过程返回 14 行,来源行数对账通过。
- 终检过滤定义检查通过。
- 临时验证脚本已清理。
- 日志未包含明文数据库密码。
## 2026-07-20 发货通知齐套与发料状态筛选修复
### 用户提问
- 用户反馈发货通知列表的“齐套”和“发料状态”筛选结果不准确,要求修改。
### 执行过程
1. 检查 `DeliveryNoticeList/index.vue` 的筛选选项与传参,确认齐套传递“是/否”,发料状态传递“发料齐套/发料缺件/未发料”,参数名称与存储过程一致。
2. 查询生产数据库 `View_生产订单_MES` 的实际值分布,确认齐套使用数值 1 或空值,发料状态使用数值 1、2 或空值;页面分别把它们映射为是/否及发料齐套/发料缺件/未发料。
3. 检查已发布的 `装配中心任务看板_发货状态查询`,发现 SAP 分支在选择任意齐套或发料状态时都使用 `OR a.TaskAID IS NULL`,导致没有匹配 MES 任务的 SAP 行无条件通过所有筛选。
4. 发现手工优先分支虽然接收两个参数,但没有应用齐套和发料状态条件,因此所有手工优先任务也会通过任意筛选。
5. 使用页面显示口径对当前生产结果进行发布前对账:全部 14 行;齐套“是”返回 10 行但有 2 行实际为否,齐套“否”返回 10 行但有 4 行实际为是;发料齐套返回 6 行但有 2 行错误,发料缺件返回 6 行且全部错误,未发料返回 14 行但有 4 行实际为发料齐套。
6. 修改 `db_backups/fix_delivery_notice_list_current_operators_20260720.sql`:从 SAP 分支的两个筛选条件中移除无条件放行 MES 空任务的逻辑,使空齐套只归入“否”、空发料状态只归入“未发料”。
7. 在手工优先分支补充与 SAP 分支完全一致的齐套和发料状态筛选条件,保证两个数据来源使用同一口径。
8. 修改 `DeliveryNoticeList/index.vue` 的发料状态格式化逻辑,将空值和非 1、2 的状态明确显示为“未发料”,并给“未发料”使用与其他未完成状态一致的提示样式。
9. 使用同一数据库连接和事务临时执行新过程,对全部五个筛选值逐项调用并检查每一行显示口径;验证齐套是 8 行、否 6 行,发料齐套 4 行、发料缺件 0 行、未发料 10 行,各分类互斥且合计均为全部 14 行,随后回滚事务。
10. 执行 `git diff --check`,没有发现空白错误,仅有仓库既有的 LF/CRLF 转换提示。
11. 尝试对页面单文件运行 ESLint检查进程 60 秒内没有输出并超时终止;随后使用仓库已安装的 `vue-template-compiler` 和 Babel 解析器检查 Vue 模板与脚本,语法解析通过。
12. 使用已通过预演的迁移脚本正式更新生产数据库,只修改查询存储过程,没有更新生产业务表数据。
13. 发布后再次以页面相同参数逐项调用生产过程并检查返回行,全部筛选均无错误数据;齐套与发料状态的各分类合计分别等于完整结果 14 行。
14. 确认发布后生产过程修改时间为 `2026-07-20 10:33:07`
15. 按仓库 `AGENTS.md` 要求追加本条完整中文执行日志,日志不包含明文数据库密码。
### 修改文件
- `src/views/ProductionManagement/DeliveryNoticeList/index.vue`
- `db_backups/fix_delivery_notice_list_current_operators_20260720.sql`
- `gptlog-process/gpdlog.md`
### 结论
- SAP 数据和手工优先数据现在执行相同的齐套、发料状态筛选规则。
- 齐套值为空时只属于“否”,不再错误进入“是”。
- 发料状态为空或不是齐套/缺件时只属于“未发料”,不再进入其他状态;页面也会明确显示“未发料”。
- 没有 MES 匹配任务的 SAP 行不再无条件通过所有筛选。
- 本次未修改生产业务数据。
### 验证结果
- SQL 事务预演和回滚通过。
- Vue 模板与脚本语法解析通过。
- 正式生产迁移发布成功。
- 当前全部 14 行;齐套是 8 行、否 6 行,分类合计 14 行。
- 当前发料齐套 4 行、发料缺件 0 行、未发料 10 行,分类合计 14 行。
- 五种筛选结果逐行显示口径检查均无错误数据。
- 生产过程修改时间检查通过。
- 日志未包含明文数据库密码。
## 2026-07-20 发货通知已完成质检任务自动隐藏
### 用户提问
- 用户要求增加发货通知列表消失条件:合格数量加不合格数量等于计划数量(订单数量)时,不再在列表显示。
### 执行过程
1. 检查当前发货查询的质检汇总,确认页面合格数量已经按终检合格数汇总,但过程尚未汇总用于判断完成状态的不合格数量。
2. 搜索仓库现有订单关闭规则,确认系统业务口径使用“终检合格数 + 收检不合格数 = 计划数量”;收检不合格品不会继续进入终检,因此不能只使用终检不合格数。
3. 查询当前发货任务的终检合格、终检不合格和收检不合格数据确认当前存在6个满足完成条件的 TaskAID6403、7968、8168、8169、8243、8405现有这些任务的不合格数均为0。
4. 确认订单6403在SAP发货源中有两条不同交货行因此6个已完成任务对应7个应从列表隐藏的结果行。
5. 修改 `db_backups/fix_delivery_notice_list_current_operators_20260720.sql``质检汇总`:终检记录汇总合格数量,收检记录汇总不合格数量,并继续按 TaskAID 形成单行结果,避免质检记录一对多扩大列表行数。
6. 在SAP分支增加消失条件有MES任务且计划数量不为空时终检合格数量与收检不合格数量之和等于计划数量的行不再输出。
7. 对没有匹配MES任务的SAP行进行显式保留避免 TaskAID、计划数量和质检数量均为空时被错误计算为 `0 = 0` 后隐藏。
8. 在手工优先分支增加相同消失条件,保证两个数据来源继续使用一致规则;计划数量为空时保留,避免空计划被误判为已完成。
9. 使用生产数据库事务临时执行新过程并使用独立来源CTE计算理论行数当前来源25行、应隐藏7行、剩余18行过程实际返回18行8169已经隐藏。
10. 在事务预演中重新调用齐套是/否和三种发料状态筛选,确认上一轮修复的筛选仍逐行准确,且各分类仍完整覆盖过滤后的结果。
11. 事务预演全部通过后回滚,没有留下生产数据库变更。
12. 执行迁移文件空白检查,未发现空白错误。
13. 使用同一迁移脚本正式更新生产数据库,仅重建查询存储过程,没有修改生产业务表数据。
14. 发布后重新调用完整过程并独立计算当前来源和隐藏数量确认来源25行、隐藏7行、列表18行8169不在列表中。
15. 发布后确认隐藏的订单结果为8168、6403两行、7968、8243、8405、8169生产过程修改时间为 `2026-07-20 10:53:26`
16. 按仓库 `AGENTS.md` 要求追加本条完整中文执行日志,日志不包含明文数据库密码。
17. 最终工作区检查发现发货页面同步出现了列顺序调整,并遗留一处新增行尾空格;完整保留列顺序修改,仅清除空白字符,最终 `git diff --check` 通过。
### 修改文件
- `db_backups/fix_delivery_notice_list_current_operators_20260720.sql`
- `gptlog-process/gpdlog.md`
### 结论
- 发货通知列表现在会自动隐藏“终检合格数量 + 收检不合格数量 = 计划数量”的已完成质检任务。
- SAP与手工优先两个来源执行相同消失条件。
- 没有MES任务或计划数量为空的数据不会被空值误判为已完成。
- 质检数量先按TaskAID汇总新增条件不会重新产生重复行或数量放大。
- 本次未修改生产业务数据。
### 验证结果
- SQL事务预演及回滚通过。
- 当前来源25行、应隐藏7行、过程剩余18行对账通过。
- 8169已从列表消失。
- 齐套与发料状态筛选回归验证通过。
- 正式生产迁移发布成功。
- 生产过程修改时间检查通过。
- 工作区空白检查通过。
- 日志未包含明文数据库密码。
## 2026-07-20 发货通知增加派发日期并调整消失条件
### 用户提问
- 用户要求在发货通知列表“齐套”后增加“派发”字段,取 `dbo.View_生产订单_MES.派工时间`,只显示年月日。
- 用户要求把消失条件调整为:终检合格数量加收检不合格数量等于计划数量,并且终检合格数量等于入库数量时才从列表消失。
### 执行过程
1. 检查发货通知页面当前列顺序,确认“齐套”后紧接“发料状态”,新增“派发”列应插入两者之间,并保留工作区中已经存在的其他列顺序调整。
2. 检查发货查询两个数据分支的输出字段,确认均可直接读取 `View_生产订单_MES.派工时间`SAP未匹配MES任务时该字段自然为空。
3. 查询当前已满足质检数量条件的任务及入库数量6403和7968终检合格数量分别为5和10但入库数量均为0应按新规则重新显示8168、8169、8243、8405的终检合格数量均等于入库数量应继续隐藏。
4. 修改SAP分支输出在齐套字段后增加 `CONVERT(date, a.派工时间) AS 派发`,由数据库直接去掉时分秒。
5. 修改手工优先分支输出同一字段并保持UNION两侧字段顺序与类型一致。
6. 修改SAP分支消失条件只有“终检合格 + 收检不合格 = 计划数量”并且“终检合格 = 入库数量”同时成立时隐藏;任一条件不成立则保留。
7. 修改手工优先分支相同条件继续显式保留计划数量为空的数据SAP分支继续保留没有MES任务的数据。
8. 修改 `DeliveryNoticeList/index.vue`,在齐套列后增加派发列,并通过页面现有 `formatDate` 再次保证只显示年月日。
9. 使用Vue模板编译器和Babel解析器检查修改后的单文件组件模板与脚本语法均通过。
10. 使用生产数据库事务临时执行新过程独立计算当前来源与理论隐藏数量当前来源25行、新规则隐藏4行、过程返回21行对账一致。
11. 事务预演逐行检查派发字段确认字段存在且所有非空日期的时分秒均为0。
12. 事务预演确认6403两条SAP交货行和7968一行已重新显示8168、8169、8243、8405仍然隐藏齐套和发料状态筛选分类仍完整覆盖全部结果。
13. 预发布空白检查通过;随后用于展示关键行的 `rg` 命令因PowerShell引号转义错误退出改用简单匹配重新检查确认代码无误该错误没有影响文件或数据库。
14. 使用已通过预演的迁移脚本正式更新生产数据库,只重建查询存储过程,没有修改生产业务表数据。
15. 发布后再次调用完整过程和独立来源查询确认来源25行、隐藏4行、列表21行派发仅含日期目标订单显示与隐藏状态均符合新规则。
16. 确认生产过程修改时间为 `2026-07-20 11:17:28`
17. 按仓库 `AGENTS.md` 要求追加本条完整中文执行日志,日志不包含明文数据库密码。
### 修改文件
- `src/views/ProductionManagement/DeliveryNoticeList/index.vue`
- `db_backups/fix_delivery_notice_list_current_operators_20260720.sql`
- `gptlog-process/gpdlog.md`
### 结论
- 发货通知列表“齐套”后已增加“派发”列,数据来自 `View_生产订单_MES.派工时间`,只显示年月日。
- 任务现在仅在质检数量完成并且全部终检合格品已经入库时消失。
- 已完成质检但尚未完全入库的任务会继续留在列表中。
- SAP与手工优先两个来源使用相同字段和消失条件。
- 本次未修改生产业务数据。
### 验证结果
- Vue模板与脚本语法解析通过。
- SQL事务预演及回滚通过。
- 当前来源25行、新规则隐藏4行、过程返回21行对账通过。
- 派发字段存在且仅包含日期。
- 6403和7968重新显示8168、8169、8243、8405继续隐藏。
- 齐套与发料状态筛选回归验证通过。
- 正式生产迁移发布成功。
- 生产过程修改时间检查通过。
- 日志未包含明文数据库密码。
## 2026-07-20 发货通知要求发货日期空值置后并按派发排序
### 用户提问
- 用户要求发货通知列表排序时把要求发货日期为空的数据放在最后,然后按照派发日期排序。
### 执行过程
1. 检查生产过程当前排序,确认使用 `ORDER BY 要求发货日期, 订单编号, 物料编号`SQL Server升序会把空日期排在最前不符合要求。
2. 调用当前生产过程检查实际顺序确认列表21行中有2条要求发货日期为空的数据订单404和7849位于列表最前。
3. 确定统一排序规则:首先按要求发货日期是否为空排序,非空在前、空值在后;然后按要求发货日期升序;同一要求发货日期内按派发升序;最后按订单编号和物料编号稳定排序。
4. 因原查询由SAP和手工优先两个SELECT通过 `UNION ALL` 组成直接在UNION排序中增加CASE表达式会受到SQL Server排序字段限制因此将两个来源包装为统一的 `发货数据` CTE。
5. 在最外层 `SELECT * FROM 发货数据` 应用统一排序,两个来源不再各自处理顺序,返回字段保持不变。
6. 使用生产数据库事务临时执行新过程,逐行检查要求发货日期:确认非空日期升序,遇到空值后不再出现非空日期。
7. 在事务预演中检查同一要求发货日期内的派发顺序确认按派发升序最后两个结果为要求发货日期为空的404、7849。
8. 首次预演输出中空日期计数没有显示原因是PowerShell变量名以 `null` 开头被解析为空值改用普通变量名后断言继续通过但中文“条”紧邻变量名又被当作变量名的一部分。该问题只影响验证文本显示不影响SQL断言、事务或排序结果。
9. 执行迁移文件空白检查和关键排序代码检查,均通过。
10. 使用已通过预演的迁移脚本正式更新生产数据库,仅重建查询存储过程,没有修改生产业务表数据。
11. 发布后再次调用完整过程并逐行验证确认列表21行、空要求发货日期2行且全部置后、末尾订单为404和7849同一要求发货日期内按派发升序。
12. 确认生产过程修改时间为 `2026-07-20 11:23:02`
13. 按仓库 `AGENTS.md` 要求追加本条完整中文执行日志,日志不包含明文数据库密码。
### 修改文件
- `db_backups/fix_delivery_notice_list_current_operators_20260720.sql`
- `gptlog-process/gpdlog.md`
### 结论
- 要求发货日期非空的数据现在排在前面,并按日期升序。
- 要求发货日期为空的数据统一排在列表最后。
- 同一要求发货日期内按派发日期升序,随后按订单编号和物料编号保持稳定顺序。
- SAP与手工优先数据在合并后统一排序。
- 本次未修改生产业务数据。
### 验证结果
- SQL事务预演及回滚通过。
- 发布后列表21行2条空要求发货日期全部置后。
- 末尾空日期订单为404、7849。
- 非空要求发货日期升序检查通过。
- 同一要求发货日期内派发升序检查通过。
- 正式生产迁移发布成功。
- 生产过程修改时间检查通过。
- 日志未包含明文数据库密码。
## 2026-07-20 发货通知查询性能优化
### 用户提问
- 用户确认发货通知列表功能已无问题,但查询速度较慢,要求优化查询性能。
### 执行过程
1. 使用生产数据库分别测量主要数据源与完整过程耗时:`View_生产订单_MES` 2723行约53毫秒SAP发货源21行约84毫秒当前装配加工记录17行约60毫秒质检记录30159行约37毫秒装配工时5362行约266毫秒完整发货过程返回21行却需要约7297毫秒。
2. 由分段耗时确认单个视图数据量并不是主要问题瓶颈位于大型CTE、UNION和多视图关联形成的执行计划。
3. 开启生产连接的 `STATISTICS IO/TIME` 采集实际统计信息确认优化前过程CPU约6625至7046毫秒、总耗时约6708至7192毫秒。
4. 统计信息显示 `YL_加工中心_操作记录表` 被扫描约972390次产生约3004694次逻辑读是主要性能问题质检表也被扫描19次并产生33858次逻辑读。
5. 查询相关视图定义和现有索引确认操作记录表现有索引以TaskAID开头当前CTE经过优化器展开后在两个结果分支及复杂视图关联中被嵌套循环反复执行。
6. 尝试查询缓存过程统计时引用了当前SQL Server版本不支持的 `last_rows`查询只读失败移除该方向后使用已经取得的实际IO、CPU和客户端计时完成定位没有修改数据库状态。
7. 选择在存储过程内部物化小型汇总结果,而不是直接新增生产表永久索引,避免扩大数据库物理结构变更范围。
8. 将当前加工操作人去重、排序和拼接结果写入会话临时表 `#当前加工操作人汇总`并按TaskAID创建唯一聚集索引原开始加工、未结束、装配工位和操作数值非空条件保持不变。
9. 将终检合格数与收检不合格数汇总写入 `#质检汇总`按TaskAID创建唯一聚集索引质检业务口径和消失条件保持不变。
10. 将装配班组合同工时汇总写入 `#合同装配工时汇总`按合同号创建索引SAP和手工优先两个分支改为关联三个已经物化且有统计信息的小结果集。
11. 本地临时表仅存在于每次过程调用的数据库会话中,过程结束后自动清理,不会在数据库留下临时业务数据,也不会在并发用户之间共享。
12. 在生产事务中临时执行优化后的过程先调用旧过程保存基准结果再调用新过程逐行逐列对比21行、43列的字段名称、字段顺序、每个字段值及最终排序完全一致。
13. 事务预演计时结果原过程7711毫秒优化过程首次编译执行3737毫秒再次执行851毫秒验证通过后回滚事务。
14. 执行迁移文件空白检查和临时表索引定义检查,均通过。
15. 使用已通过预演的迁移脚本正式更新生产数据库,仅重建查询存储过程,没有修改生产业务表数据或新增永久索引。
16. 发布后连续执行三次完整查询耗时分别为587毫秒、557毫秒、558毫秒结果保持21行、43列相比发布前7711毫秒常规查询速度约提升13倍。
17. 发布后重新采集统计信息操作记录相关扫描由约972390次降至合计约106617次逻辑读由约3004694次降至约334468次总CPU约1800毫秒、数据库端耗时约604毫秒。
18. 发布后确认消失条件、派发字段和排序结果均保持不变6403两行仍显示8168、8169、8243、8405仍隐藏2条空要求发货日期仍位于末尾404、7849。
19. 发布后逐项调用齐套是/否和发料齐套/缺件/未发料筛选逐行显示口径检查通过两组分类合计均等于完整结果21行。
20. 确认生产过程修改时间为 `2026-07-20 11:29:55`
21. 按仓库 `AGENTS.md` 要求追加本条完整中文执行日志,日志不包含明文数据库密码。
### 修改文件
- `db_backups/fix_delivery_notice_list_current_operators_20260720.sql`
- `gptlog-process/gpdlog.md`
### 结论
- 发货通知完整查询由约7.7秒降低到约0.56秒常规查询速度约提升13倍。
- 性能提升来自将操作人、质检和合同工时汇总各执行一次并物化避免CTE在复杂关联中被反复扫描。
- 返回的21行、43列及所有字段值、顺序和业务筛选与优化前完全一致。
- 优化只使用过程内会话临时表和临时索引,没有新增永久数据库对象或修改生产业务数据。
### 验证结果
- 生产事务预演及回滚通过。
- 优化前后21行、43列逐行逐列对比一致。
- 发布后连续三次耗时587毫秒、557毫秒、558毫秒。
- 操作记录逻辑读由约300万降低到约33万。
- 关键订单显示与隐藏状态回归通过。
- 要求发货日期和派发排序回归通过。
- 齐套与发料状态筛选回归通过。
- 正式生产迁移发布成功。
- 生产过程修改时间检查通过。
- 日志未包含明文数据库密码。
## 2026-07-20 整理今日修改清单
### 用户提问
- 用户要求整理今天完成的修改。
### 执行过程
1. 检索 `gptlog-process/gpdlog.md` 中日期为2026-07-20的标题共确认13段此前执行记录覆盖设计工时报表权限、设计任务多选、排产日程加工状态和发货通知列表审查、修复与优化。
2. 检查当前Git工作区和差异统计确认今日已记录业务修改涉及5个Vue页面、3个数据库迁移文件以及持续追加的中文过程日志。
3. 逐项复核设计工时报表权限迁移和页面参数,确认普通用户本人范围、领导/管理员全部范围以及两个生产查询过程均已发布和验证。
4. 复核设计任务页面差异确认指派对象与对齐可见多选、远程查询保留、历史ID姓名还原和列表多人显示均属于今日修改。
5. 复核两个排产页面差异确认日程从设备状态过程读取当前加工TaskAID并以绿色优先显示正在加工任务。
6. 根据发货通知今日9段连续日志整理最终状态包括双来源合并、重复消除、终检数量、当前操作人、筛选、消失条件、派发日期、排序及性能优化以最终规则为准避免把中间规则误写成最终结论。
7. 核对生产发布验证结果确认设计权限两个过程和发货通知查询过程均已发布发货查询最终保持21行、43列并由约7.7秒降低到约0.56秒。
8. 检查未记录差异,发现 `src/views/PlanManagement/SelfMakePlando/index.vue` 另有一行“产品单位”表格列修改该项不在今日GPT执行日志中整理时单独标注为现有未归属改动不声称由本轮实现或验证。
9. 检查当前工作区状态确认所有修改仍未提交7个业务Vue文件和日志为已修改状态3个数据库迁移文件为未跟踪状态整理过程不执行提交、推送或业务代码修改。
10. 按仓库 `AGENTS.md` 要求追加本条完整中文执行日志,日志不包含数据库凭据。
### 修改文件
- `gptlog-process/gpdlog.md`
### 结论
- 今日已记录的功能修改可归纳为四类:设计工时报表权限、设计任务多人指派、排产日程加工中绿色标识、发货通知列表完整修复与性能优化。
- 设计权限与发货通知数据库过程已发布生产并完成数据对账;设计任务和排产页面为前端代码修改。
- 当前工作区修改尚未提交3个数据库迁移文件尚未纳入版本控制。
- `SelfMakePlando/index.vue` 的“产品单位”列属于当前存在但未记录归属的额外修改。
### 验证结果
- 今日13段执行日志标题核对完成。
- 当前Vue与SQL修改文件清单核对完成。
- 生产发布状态和最终业务规则核对完成。
- 未归属工作区差异已单独识别。
- 本次仅整理和记录,没有修改业务代码、生产过程或业务数据。
## 2026-07-20 根据发货任务堵点文档生成明日计划
### 用户提问
- 用户要求根据桌面 `发货任务堵点.docx` 生成明日计划上午先对接并确认文档内容随后按文档开发、测试和与客户确认预计持续到13:20-14:20下午分析设计报工工时整体流程并建档梳理入口、功能、存储过程、表、视图和页面同时预留处理线上临时问题的时间。
- 用户要求沿用给出的时间段格式,每小时拆分为六条记录,内容允许重复。
### 执行过程
1. 使用只读方式打开 `C:/Users/meswork764/Desktop/发货任务堵点.docx` 内部Open XML没有修改原文档也没有生成临时解压文件。
2. 提取文档内容,确认需求覆盖仓库任务大屏、大厅计划大屏、质检测试大屏和装配大屏。
3. 确认发货数据来源由SAP视图 `[SAP].[SBO_YL].[dbo].[UBT_ODRF_ODLNMES]` 与MES优先任务组成并包含物料编码为3420-YT、3420-HT时查看子任务的特殊规则。
4. 提取堵点判断顺序:齐套、派发、发料、开工、装配、质检、仓库;提取四类看板各自的数据范围和隐藏规则。
5. 识别文档中的待确认点:装配判断的“继续”和“堵点显示”两条条件都写成完成数量等于计划数量,明日计划中安排与客户确认正确的反向条件。
6. 按用户给出的8个时间段组织计划完整一小时按每10分钟一条记录拆为六条。
7. `10:30-11:50` 共80分钟拆分为8条10分钟记录`17:20-18:00` 共40分钟拆分为4条10分钟记录全天合计48条记录。
8. 上午计划覆盖需求逐条确认、数据源和字段对照、公共堵点逻辑开发、四类看板接入、测试及客户验收确认。
9. 下午计划覆盖设计报工流程入口、页面功能、接口调用、存储过程、表和视图依赖、数据流及权限流程建档,并在各阶段预留线上问题定位和修正。
10. 本次只生成计划文本并追加过程日志没有修改业务代码、数据库过程、生产数据或原始Word文档。
### 修改文件
- `gptlog-process/gpdlog.md`
### 结论
- 已按每10分钟一条记录生成8个时间段、共48条明日计划。
- 上午以发货任务堵点需求对接、开发、测试和客户确认为主13:20-14:20完成联调验收和问题修正。
- 下午以设计报工工时全流程分析建档为主,覆盖入口、功能、页面、存储过程、表、视图和数据关系,并兼顾线上临时问题。
- 文档中装配判断条件重复的问题已明确列为需求确认项。
### 验证结果
- Word文档内容读取完成。
- 8个时间段全部覆盖。
- 完整小时均拆分为6条10分钟记录。
- 非完整小时按实际分钟数拆分总计48条。
- 本次未修改原始文档和业务资源。
## 2026-07-20 调整明日计划记录格式
### 用户提问
- 用户要求去掉明日计划中“108:30-08:40”一类子序号和子时间格式任务可以写得稍大一些允许重复。
### 执行过程
1. 保留用户给出的8个主时间段和“明日计划”总体结构。
2. 每个主时间段仍安排6条记录便于按下发要求录入共48条。
3. 删除每条记录前的子序号和10分钟起止时间只保留任务描述。
4. 将过细的字段级、步骤级内容合并为需求对接、数据梳理、功能开发、联调测试、客户确认、流程建档和问题处理等较大工作项。
5. 上午继续围绕发货任务堵点文档开展对接、开发、测试和客户确认;下午继续围绕设计报工工时整体流程开展页面、过程、表、视图和数据流分析建档。
6. 对开发、测试、需求确认、文档整理和线上问题处理等持续性工作允许在同一或相邻时间段重复记录。
7. 本次只调整计划文本和追加过程日志没有修改业务代码、数据库、生产数据或原始Word文档。
### 修改文件
- `gptlog-process/gpdlog.md`
### 结论
- 明日计划已改为8个主时间段、每段6条大工作项。
- 每条记录不再包含子序号和10分钟时间格式。
- 工作项粒度更适合报工填写,持续性任务允许重复。
### 验证结果
- 8个主时间段保留。
- 每段6条记录共48条。
- 子序号和子时间已移除。
- 本次未修改业务资源。
## 2026-07-21 上传所有修改
### 用户提问
- 用户要求上传当前工作区中的所有修改。
### 执行过程
1. 检查 Git 状态,确认当前分支为 `snapshot/local-save-20260625-154806`,并已跟踪远端分支 `origin/snapshot/local-save-20260625-154806`
2. 检查远端配置,确认拉取和推送地址均为 `origin` 对应的 MES 前端仓库。
3. 核对工作区全部修改,确认内容涵盖计划日历加工状态着色、自制计划产品单位、发货任务看板字段与数据合并、设计任务人员显示、设计报工工时报表权限、委外页面调整,以及 3 份数据库备份脚本;`materialReturn.vue` 最初显示为修改,暂存规范化后确认没有实际内容差异,因此未进入提交。
4. 执行 `git diff --check`,未发现尾随空格或空白格式错误;仅出现 Git 关于部分文件后续可能由 LF 转换为 CRLF 的提示。
5. 首次执行 `npm run build` 时因 124 秒命令时限到期而未返回结果,因此提高命令时限后重新执行。
6. 第二次执行 `npm run build` 成功Webpack 编译完成仅有资源体积超出建议值、Browserslist 数据过期等非阻断警告,没有编译错误。
7. 将本次中文执行日志追加至 `gptlog-process/gpdlog.md`,随后使用 `git add -A` 暂存全部修改。
8. 将全部暂存内容提交,并推送至远端当前分支 `origin/snapshot/local-save-20260625-154806`
9. 推送后复核本地分支与远端分支状态,确认全部修改已上传且工作区无未提交文件。
### 修改文件
- `gptlog-process/gpdlog.md`
- `src/views/PlanManagement/SelfMakePlando/index.vue`
- `src/views/PlanManagement/SelfMakePlandone/index.vue`
- `src/views/PlanManagement/WorkstationPlan/index.vue`
- `src/views/ProductionManagement/DeliveryNoticeList/index.vue`
- `src/views/ProductionManagement/DesignReportTask/HoursReport/index.vue`
- `src/views/ProductionManagement/DesignReportTask/Task/index.vue`
- `src/views/ProductionManagement/SaleOutsourceMange/index.vue`
- `db_backups/add_design_report_hours_report_permissions_20260720.sql`
- `db_backups/fix_delivery_notice_list_current_operators_20260720.sql`
- `db_backups/fix_delivery_notice_list_data_merge_20260720.sql`
### 结论
- 当前工作区的全部修改已统一提交并推送到远端当前分支。
- 项目生产构建验证通过,没有阻断上传的编译错误。
### 验证结果
- `git diff --check`:通过。
- `npm run build`:通过,存在非阻断警告。
- Git 推送:成功。
- 推送后工作区:干净,本地分支与远端分支同步。
## 2026-07-20 评估明日计划可完成性
### 用户提问
- 用户询问调整后的明日计划是否合理、能否完成。
### 执行过程
1. 将计划区分为“报工记录拆分”和“实际交付承诺”两个维度评估避免因为48条记录数量较多而误判为48个独立交付项。
2. 复核上午发货堵点范围,确认涉及公共数据源、七级堵点判断、特殊物料子任务、四个任务大屏、各自隐藏规则、测试和客户确认,实际范围较大。
3. 识别需求未完全确定的风险:文档装配判断正反条件重复、质检“前序不合格数”口径、仓库不合格数来源、特殊物料子任务展示方式仍需客户确认。
4. 评估上午有效工作时间约4小时40分钟若已有发货查询基础可以复用、客户及时确认且四个大屏共用后端输出完成公共查询、主要页面接入和首轮测试有可能但四屏全部开发、完整回归和客户修改在14:20前完成存在较高风险。
5. 评估下午设计报工流程建档范围页面、功能、存储过程、表、视图和数据流的第一版目录及主流程可以在约3小时内完成若要求逐字段、逐参数验证并同时处理线上问题则难以当天形成完整定稿。
6. 建议增加14:20阶段检查点发货功能按期通过时切换报工建档若仍有联调问题优先保证发货功能闭环将报工建档目标降为第一版框架和对象清单。
7. 建议把需求确认、公共堵点查询、至少一个核心看板接入、首轮测试和报工流程第一版文档设为必须完成项;四个看板全部优化、客户新增调整、完整报工技术档案作为争取完成项。
8. 本次只进行计划评估并追加过程日志,没有修改计划文件、业务代码、数据库或生产数据。
### 修改文件
- `gptlog-process/gpdlog.md`
### 结论
- 该计划用于报工填写是合理的,任务方向和时间顺序基本正确。
- 该计划作为当天全部交付承诺偏满,主要风险是四个大屏同时开发测试、客户确认时效以及临时线上问题。

View File

@@ -375,6 +375,7 @@
<el-table-column align="center" prop="计划数量" label="计划数量" width="100" /> <el-table-column align="center" prop="计划数量" label="计划数量" width="100" />
<el-table-column align="center" prop="存货量" label="存货量" width="80" /> <el-table-column align="center" prop="存货量" label="存货量" width="80" />
<el-table-column align="center" prop="材质" label="材质" width="80" /> <el-table-column align="center" prop="材质" label="材质" width="80" />
<el-table-column align="center" prop="产品单位" label="产品单位" width="80" />
</el-table> </el-table>
</el-card> </el-card>
</el-dialog> </el-dialog>

View File

@@ -472,6 +472,7 @@ export default {
loading: false, loading: false,
tableData: [], tableData: [],
donetableData: [], donetableData: [],
machiningTaskIds: [],
multipleSelection: [], multipleSelection: [],
dialogVisible: false, dialogVisible: false,
@@ -562,7 +563,7 @@ export default {
computed: { computed: {
calendarEvents() { calendarEvents() {
return this.tableData.map(item => { return this.tableData.map(item => {
const isPriority = item.优先级 === '是' const eventStyle = this.getCalendarEventStyle(item)
return { return {
id: `${item.订单号}-${item.订单行号}-${item.拆分内码}`, id: `${item.订单号}-${item.订单行号}-${item.拆分内码}`,
@@ -577,17 +578,17 @@ export default {
计划数量: item.计划数量, 计划数量: item.计划数量,
优先级: item.优先级 优先级: item.优先级
}, },
backgroundColor: isPriority ? '#f56c6c' : '#409EFF', // 优先级高为红色,普通为蓝色 backgroundColor: eventStyle.color,
borderColor: isPriority ? '#f56c6c' : '#409EFF', borderColor: eventStyle.color,
textColor: isPriority ? '#fff' : '#fff', // 白色文字 textColor: '#fff',
classNames: isPriority ? ['priority-event'] : ['normal-event'], classNames: [eventStyle.className]
} }
}) })
}, },
donecalendarEvents() { donecalendarEvents() {
return this.donetableData.map(item => { return this.donetableData.map(item => {
const isPriority = item.优先级 === '是' const eventStyle = this.getCalendarEventStyle(item)
return { return {
id: `${item.订单号}-${item.订单行号}-${item.拆分内码}`, id: `${item.订单号}-${item.订单行号}-${item.拆分内码}`,
@@ -603,10 +604,10 @@ export default {
优先级: item.优先级, 优先级: item.优先级,
产品编码:item.产品编码 产品编码:item.产品编码
}, },
backgroundColor: isPriority ? '#f56c6c' : '#409EFF', // 优先级高为红色,普通为蓝色 backgroundColor: eventStyle.color,
borderColor: isPriority ? '#f56c6c' : '#409EFF', borderColor: eventStyle.color,
textColor: isPriority ? '#fff' : '#fff', // 白色文字 textColor: '#fff',
classNames: isPriority ? ['priority-event'] : ['normal-event'] classNames: [eventStyle.className]
} }
}) })
} }
@@ -628,6 +629,7 @@ export default {
}, },
doneactiveTab(newVal) { doneactiveTab(newVal) {
if (newVal === 'doneschedule') { if (newVal === 'doneschedule') {
this.loadMachiningTaskIds()
this.$nextTick(() => { this.$nextTick(() => {
// 判断日历的HTML Dom 是否存在 // 判断日历的HTML Dom 是否存在
const calendarApi = this.$refs.donefullCalendar && this.$refs.donefullCalendar.getApi() const calendarApi = this.$refs.donefullCalendar && this.$refs.donefullCalendar.getApi()
@@ -668,6 +670,9 @@ export default {
} }
}, },
deep: true deep: true
},
machiningTaskIds() {
this.refreshVisibleCalendarEvents()
} }
}, },
created() { created() {
@@ -683,6 +688,43 @@ export default {
setInterval(this.getCurrentTime, 1000); setInterval(this.getCurrentTime, 1000);
}, },
methods: { methods: {
normalizeTaskAid(value) {
return value === null || value === undefined ? '' : String(value).trim()
},
getTaskAid(item) {
if (!item) return ''
return this.normalizeTaskAid(item.taskaid || item.TaskAID || item.AID)
},
isMachiningTask(item) {
const taskAid = this.getTaskAid(item)
return taskAid !== '' && this.machiningTaskIds.includes(taskAid)
},
getCalendarEventStyle(item) {
if (this.isMachiningTask(item)) return { color: '#67c23a', className: 'machining-event' }
if (item.优先级 === '是') return { color: '#f56c6c', className: 'priority-event' }
return { color: '#409EFF', className: 'normal-event' }
},
loadMachiningTaskIds() {
const data = this.CreateData('11', '设备管理_设备状态_查询', [['设备名称', '']])
return this.ExecDatabase(data).then(response => {
const rows = Array.isArray(response.data) ? response.data : []
this.machiningTaskIds = Array.from(new Set(rows
.map(item => this.normalizeTaskAid(item.TaskAID || item.taskaid || item.AID))
.filter(Boolean)))
}).catch(error => {
console.error('机加正在加工任务查询失败:', error)
})
},
refreshVisibleCalendarEvents() {
if (this.activeTab === 'schedule') this.calendarOptions.events = this.calendarEvents
if (this.doneactiveTab === 'doneschedule') this.donecalendarOptions.events = this.donecalendarEvents
this.$nextTick(() => {
const calendar = this.$refs.fullCalendar && this.$refs.fullCalendar.getApi()
const doneCalendar = this.$refs.donefullCalendar && this.$refs.donefullCalendar.getApi()
if (calendar && this.activeTab === 'schedule') calendar.refetchEvents()
if (doneCalendar && this.doneactiveTab === 'doneschedule') doneCalendar.refetchEvents()
})
},
//you //you
getitemdata(item){ getitemdata(item){
var param = [] var param = []
@@ -917,6 +959,7 @@ export default {
}); });
}, },
donesearchTable() { donesearchTable() {
this.loadMachiningTaskIds()
this.loading = true this.loading = true
this.donetableData = [] this.donetableData = []
var param = [] var param = []

View File

@@ -458,6 +458,7 @@ export default {
loading: false, loading: false,
tableData: [], tableData: [],
donetableData: [], donetableData: [],
machiningTaskIds: [],
expandedStations: {}, expandedStations: {},
expandedDates: {}, expandedDates: {},
@@ -635,7 +636,7 @@ export default {
}, },
calendarEvents() { calendarEvents() {
return this.tableData.map(item => { return this.tableData.map(item => {
const isPriority = item.优先级 === '是' const eventStyle = this.getCalendarEventStyle(item)
return { return {
id: `${item.订单号}-${item.订单行号}-${item.拆分内码}`, id: `${item.订单号}-${item.订单行号}-${item.拆分内码}`,
@@ -650,17 +651,17 @@ export default {
计划数量: item.计划数量, 计划数量: item.计划数量,
优先级: item.优先级 优先级: item.优先级
}, },
backgroundColor: isPriority ? '#f56c6c' : '#409EFF', // 优先级高为红色,普通为蓝色 backgroundColor: eventStyle.color,
borderColor: isPriority ? '#f56c6c' : '#409EFF', borderColor: eventStyle.color,
textColor: isPriority ? '#fff' : '#fff', // 白色文字 textColor: '#fff',
classNames: isPriority ? ['priority-event'] : ['normal-event'], classNames: [eventStyle.className]
} }
}) })
}, },
donecalendarEvents() { donecalendarEvents() {
return this.donetableData.map(item => { return this.donetableData.map(item => {
const isPriority = item.优先级 === '是' const eventStyle = this.getCalendarEventStyle(item)
return { return {
id: `${item.订单号}-${item.订单行号}-${item.拆分内码}`, id: `${item.订单号}-${item.订单行号}-${item.拆分内码}`,
@@ -676,10 +677,10 @@ export default {
优先级: item.优先级, 优先级: item.优先级,
产品编码:item.产品编码 产品编码:item.产品编码
}, },
backgroundColor: isPriority ? '#f56c6c' : '#409EFF', // 优先级高为红色,普通为蓝色 backgroundColor: eventStyle.color,
borderColor: isPriority ? '#f56c6c' : '#409EFF', borderColor: eventStyle.color,
textColor: isPriority ? '#fff' : '#fff', // 白色文字 textColor: '#fff',
classNames: isPriority ? ['priority-event'] : ['normal-event'] classNames: [eventStyle.className]
} }
}) })
} }
@@ -701,6 +702,7 @@ export default {
}, },
doneactiveTab(newVal) { doneactiveTab(newVal) {
if (newVal === 'doneschedule') { if (newVal === 'doneschedule') {
this.loadMachiningTaskIds()
this.$nextTick(() => { this.$nextTick(() => {
// 判断日历的HTML Dom 是否存在 // 判断日历的HTML Dom 是否存在
const calendarApi = this.$refs.donefullCalendar && this.$refs.donefullCalendar.getApi() const calendarApi = this.$refs.donefullCalendar && this.$refs.donefullCalendar.getApi()
@@ -741,6 +743,9 @@ export default {
} }
}, },
deep: true deep: true
},
machiningTaskIds() {
this.refreshVisibleCalendarEvents()
} }
}, },
created() { created() {
@@ -756,6 +761,43 @@ export default {
setInterval(this.getCurrentTime, 1000); setInterval(this.getCurrentTime, 1000);
}, },
methods: { methods: {
normalizeTaskAid(value) {
return value === null || value === undefined ? '' : String(value).trim()
},
getTaskAid(item) {
if (!item) return ''
return this.normalizeTaskAid(item.taskaid || item.TaskAID || item.AID)
},
isMachiningTask(item) {
const taskAid = this.getTaskAid(item)
return taskAid !== '' && this.machiningTaskIds.includes(taskAid)
},
getCalendarEventStyle(item) {
if (this.isMachiningTask(item)) return { color: '#67c23a', className: 'machining-event' }
if (item.优先级 === '是') return { color: '#f56c6c', className: 'priority-event' }
return { color: '#409EFF', className: 'normal-event' }
},
loadMachiningTaskIds() {
const data = this.CreateData('11', '设备管理_设备状态_查询', [['设备名称', '']])
return this.ExecDatabase(data).then(response => {
const rows = Array.isArray(response.data) ? response.data : []
this.machiningTaskIds = Array.from(new Set(rows
.map(item => this.normalizeTaskAid(item.TaskAID || item.taskaid || item.AID))
.filter(Boolean)))
}).catch(error => {
console.error('机加正在加工任务查询失败:', error)
})
},
refreshVisibleCalendarEvents() {
if (this.activeTab === 'schedule') this.calendarOptions.events = this.calendarEvents
if (this.doneactiveTab === 'doneschedule') this.donecalendarOptions.events = this.donecalendarEvents
this.$nextTick(() => {
const calendar = this.$refs.fullCalendar && this.$refs.fullCalendar.getApi()
const doneCalendar = this.$refs.donefullCalendar && this.$refs.donefullCalendar.getApi()
if (calendar && this.activeTab === 'schedule') calendar.refetchEvents()
if (doneCalendar && this.doneactiveTab === 'doneschedule') doneCalendar.refetchEvents()
})
},
stationDateKey(station, date) { stationDateKey(station, date) {
return `${station}__${date}` return `${station}__${date}`
}, },
@@ -1092,6 +1134,7 @@ export default {
}); });
}, },
donesearchTable() { donesearchTable() {
this.loadMachiningTaskIds()
this.loading = true this.loading = true
this.donetableData = [] this.donetableData = []
var param = [] var param = []

View File

@@ -86,22 +86,13 @@
tooltip-effect="dark" tooltip-effect="dark"
> >
<el-table-column align="center" fixed label="序号" type="index" width="50" /> <el-table-column align="center" fixed label="序号" type="index" width="50" />
<el-table-column align="center" fixed label="生产订单" prop="订单编号" width="90" />
<el-table-column align="center" label="销售订单" prop="合同号" width="110" /> <el-table-column align="center" label="销售订单" prop="合同号" width="110" />
<el-table-column align="center" fixed label="生产订单" prop="订单编号" width="90" />
<el-table-column align="center" label="物料名称" prop="物料描述" width="160" /> <el-table-column align="center" label="物料名称" prop="物料描述" width="160" />
<el-table-column align="center" label="物料编码" prop="物料编号" min-width="230" show-overflow-tooltip /> <el-table-column align="center" label="物料编码" prop="物料编号" min-width="230" show-overflow-tooltip />
<el-table-column align="center" label="订单数量" width="90"> <el-table-column align="center" label="订单数量" width="90">
<template slot-scope="scope">{{ formatQuantity(scope.row.计划数量) }}</template> <template slot-scope="scope">{{ formatQuantity(scope.row.计划数量) }}</template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="入库数量" width="90">
<template slot-scope="scope">{{ formatQuantity(scope.row.入库数量) }}</template>
</el-table-column>
<el-table-column align="center" label="完成数量" width="90">
<template slot-scope="scope">{{ formatQuantity(scope.row.完成数量) }}</template>
</el-table-column>
<el-table-column align="center" label="合格数量" width="90">
<template slot-scope="scope">{{ formatQuantity(scope.row.合格数量) }}</template>
</el-table-column>
<el-table-column align="center" label="要求发货日期" width="120"> <el-table-column align="center" label="要求发货日期" width="120">
<template slot-scope="scope">{{ formatDate(scope.row.要求发货日期) }}</template> <template slot-scope="scope">{{ formatDate(scope.row.要求发货日期) }}</template>
</el-table-column> </el-table-column>
@@ -112,6 +103,9 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="派发" width="100">
<template slot-scope="scope">{{ formatDate(scope.row.派发) }}</template>
</el-table-column>
<el-table-column align="center" label="发料状态" width="110"> <el-table-column align="center" label="发料状态" width="110">
<template slot-scope="scope"> <template slot-scope="scope">
<div :style="getStatusStyle(formatSendStatus(scope.row.发料状态))" class="score-cell"> <div :style="getStatusStyle(formatSendStatus(scope.row.发料状态))" class="score-cell">
@@ -119,7 +113,6 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="操作人" prop="操作人" width="100" />
<el-table-column align="center" label="装配开工" width="100"> <el-table-column align="center" label="装配开工" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<div :style="getStatusStyle(formatStartStatus(scope.row.任务状态))" class="score-cell"> <div :style="getStatusStyle(formatStartStatus(scope.row.任务状态))" class="score-cell">
@@ -127,6 +120,17 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="完成数量" width="90">
<template slot-scope="scope">{{ formatQuantity(scope.row.完成数量) }}</template>
</el-table-column>
<el-table-column align="center" label="合格数量" width="90">
<template slot-scope="scope">{{ formatQuantity(scope.row.合格数量) }}</template>
</el-table-column>
<el-table-column align="center" label="入库数量" width="90">
<template slot-scope="scope">{{ formatQuantity(scope.row.入库数量) }}</template>
</el-table-column>
<el-table-column align="center" label="操作人" prop="操作人" width="100" />
</el-table> </el-table>
</el-card> </el-card>
</div> </div>
@@ -195,7 +199,7 @@ export default {
if (value === '发料齐套' || value === '发料缺件') return value if (value === '发料齐套' || value === '发料缺件') return value
if (Number(value || 0) === 1) return '发料齐套' if (Number(value || 0) === 1) return '发料齐套'
if (Number(value || 0) === 2) return '发料缺件' if (Number(value || 0) === 2) return '发料缺件'
return '' return '未发料'
}, },
formatStartStatus(value) { formatStartStatus(value) {
return Number(value || 0) > 0 ? '已开工' : '待执行' return Number(value || 0) > 0 ? '已开工' : '待执行'
@@ -207,7 +211,7 @@ export default {
color: '#67c23a' color: '#67c23a'
} }
} }
if (value === '否' || value === '发料缺件' || value === '待执行') { if (value === '否' || value === '发料缺件' || value === '未发料' || value === '待执行') {
return { return {
backgroundColor: '#fdf6ec', backgroundColor: '#fdf6ec',
color: '#e6a23c' color: '#e6a23c'

View File

@@ -219,7 +219,9 @@ export default {
['项目号', this.searchForm.projectNo || ''], ['项目号', this.searchForm.projectNo || ''],
['物料编码', this.searchForm.itemCode || ''], ['物料编码', this.searchForm.itemCode || ''],
['类别', this.searchForm.category || ''], ['类别', this.searchForm.category || ''],
['DID', this.searchForm.did || 0] ['DID', this.searchForm.did || 0],
['当前操作人', this.currentUserName()],
['角色编号', this.currentRoleId()]
] ]
}, },
async searchTable() { async searchTable() {
@@ -413,6 +415,12 @@ export default {
}, },
formatProjectLabel(item) { formatProjectLabel(item) {
return item.项目名称 ? `${item.项目号} | ${item.项目名称}` : item.项目号 return item.项目名称 ? `${item.项目号} | ${item.项目名称}` : item.项目号
},
currentUserName() {
return (this.$store && this.$store.getters && this.$store.getters.name) || ''
},
currentRoleId() {
return (this.$store && this.$store.getters && this.$store.getters.token) || ''
} }
} }
} }

View File

@@ -136,7 +136,11 @@
</el-table-column> </el-table-column>
<el-table-column align="left" label="任务描述" prop="任务描述" width="320" show-overflow-tooltip /> <el-table-column align="left" label="任务描述" prop="任务描述" width="320" show-overflow-tooltip />
<el-table-column align="left" label="设计要求" prop="设计要求" width="320" show-overflow-tooltip /> <el-table-column align="left" label="设计要求" prop="设计要求" width="320" show-overflow-tooltip />
<el-table-column align="left" label="指派对象" prop="指派对象" width="220" show-overflow-tooltip /> <el-table-column align="left" label="指派对象" prop="指派对象" width="220" show-overflow-tooltip>
<template slot-scope="scope">
<span>{{ formatAssigneeNames(scope.row) }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="预计开始" prop="预计开始时间" width="180" /> <el-table-column align="center" label="预计开始" prop="预计开始时间" width="180" />
<el-table-column align="center" label="预计结束" prop="预计结束时间" width="180" /> <el-table-column align="center" label="预计结束" prop="预计结束时间" width="180" />
<el-table-column align="left" label="进度说明" prop="进度说明" width="360"> <el-table-column align="left" label="进度说明" prop="进度说明" width="360">
@@ -437,6 +441,9 @@ export default {
parentMaterialOptions: [], parentMaterialOptions: [],
personnelOptions: [], personnelOptions: [],
visibilityPersonnelOptions: [], visibilityPersonnelOptions: [],
personnelNameMap: {},
personnelQueryId: 0,
visibilityPersonnelQueryId: 0,
noteForm: { noteForm: {
DID: '', DID: '',
任务描述: '', 任务描述: '',
@@ -537,14 +544,15 @@ export default {
this.formData = this.getEmptyForm() this.formData = this.getEmptyForm()
this.loadDefaultProjectOptions() this.loadDefaultProjectOptions()
this.loadDefaultMaterialOptions() this.loadDefaultMaterialOptions()
this.queryPersonnel('')
this.queryVisibilityPersonnel('') this.queryVisibilityPersonnel('')
this.dialogVisible = true this.dialogVisible = true
this.$nextTick(() => this.$refs.taskForm && this.$refs.taskForm.clearValidate()) this.$nextTick(() => this.$refs.taskForm && this.$refs.taskForm.clearValidate())
}, },
openEdit(row) { openEdit(row) {
this.isEdit = true this.isEdit = true
const assigneeIds = row.指派对象ID ? String(row.指派对象ID).split(',').filter(Boolean) : [] const assigneeIds = this.normalizePersonnelIds(row.指派对象ID)
const visibilityIds = row.对齐可见ID ? String(row.对齐可见ID).split(',').filter(Boolean) : [] const visibilityIds = this.normalizePersonnelIds(row.对齐可见ID)
this.formData = { this.formData = {
...this.getEmptyForm(), ...this.getEmptyForm(),
...row, ...row,
@@ -557,6 +565,8 @@ export default {
this.ensurePersonnelOptions(this.visibilityPersonnelOptions, visibilityIds, row.对齐可见) this.ensurePersonnelOptions(this.visibilityPersonnelOptions, visibilityIds, row.对齐可见)
this.loadDefaultProjectOptions() this.loadDefaultProjectOptions()
this.loadDefaultMaterialOptions() this.loadDefaultMaterialOptions()
this.queryPersonnel('')
this.queryVisibilityPersonnel('')
this.dialogVisible = true this.dialogVisible = true
this.$nextTick(() => this.$refs.taskForm && this.$refs.taskForm.clearValidate()) this.$nextTick(() => this.$refs.taskForm && this.$refs.taskForm.clearValidate())
}, },
@@ -819,21 +829,33 @@ export default {
} }
}, },
async queryPersonnel(query) { async queryPersonnel(query) {
const requestId = ++this.personnelQueryId
const data = this.CreateData('11', '设计报工_人员查询', [['过滤', query || '']]) const data = this.CreateData('11', '设计报工_人员查询', [['过滤', query || '']])
try { try {
const response = await this.ExecDatabase(data) const response = await this.ExecDatabase(data)
this.personnelOptions = response.data || [] if (requestId !== this.personnelQueryId) return
const rows = response.data || []
this.cachePersonnelOptions(rows)
this.personnelOptions = this.mergePersonnelOptions(this.personnelOptions, rows, this.formData.assigneeIds)
} catch (error) { } catch (error) {
this.personnelOptions = [] if (requestId === this.personnelQueryId) {
this.personnelOptions = this.mergePersonnelOptions(this.personnelOptions, [], this.formData.assigneeIds)
}
} }
}, },
async queryVisibilityPersonnel(query) { async queryVisibilityPersonnel(query) {
const requestId = ++this.visibilityPersonnelQueryId
const data = this.CreateData('11', '设计报工_人员查询', [['过滤', query || '']]) const data = this.CreateData('11', '设计报工_人员查询', [['过滤', query || '']])
try { try {
const response = await this.ExecDatabase(data) const response = await this.ExecDatabase(data)
this.visibilityPersonnelOptions = response.data || [] if (requestId !== this.visibilityPersonnelQueryId) return
const rows = response.data || []
this.cachePersonnelOptions(rows)
this.visibilityPersonnelOptions = this.mergePersonnelOptions(this.visibilityPersonnelOptions, rows, this.formData.visibilityIds)
} catch (error) { } catch (error) {
this.visibilityPersonnelOptions = [] if (requestId === this.visibilityPersonnelQueryId) {
this.visibilityPersonnelOptions = this.mergePersonnelOptions(this.visibilityPersonnelOptions, [], this.formData.visibilityIds)
}
} }
}, },
handleMaterialChange(value) { handleMaterialChange(value) {
@@ -845,23 +867,63 @@ export default {
this.formData.关联父件物料名称 = selected ? selected.物料名称 : '' this.formData.关联父件物料名称 = selected ? selected.物料名称 : ''
}, },
handleAssigneeChange(values) { handleAssigneeChange(values) {
const selected = this.personnelOptions.filter(item => values.includes(item.人员编号)) const ids = this.normalizePersonnelIds(values)
this.formData.指派对象ID = values.join(',') this.formData.assigneeIds = ids
this.formData.指派对象 = selected.map(item => item.人员姓名).join(',') this.formData.指派对象ID = ids.join(',')
this.formData.指派对象 = this.getPersonnelNames(ids, this.formData.指派对象).join(',')
}, },
handleVisibilityChange(values) { handleVisibilityChange(values) {
const selected = this.visibilityPersonnelOptions.filter(item => values.includes(item.人员编号)) const ids = this.normalizePersonnelIds(values)
this.formData.对齐可见ID = values.join(',') this.formData.visibilityIds = ids
this.formData.对齐可见 = selected.map(item => item.人员姓名).join(',') this.formData.对齐可见ID = ids.join(',')
this.formData.对齐可见 = this.getPersonnelNames(ids, this.formData.对齐可见).join(',')
}, },
ensurePersonnelOptions(options, ids, namesValue) { ensurePersonnelOptions(options, ids, namesValue) {
const names = namesValue ? String(namesValue).split(',') : [] const normalizedIds = this.normalizePersonnelIds(ids)
ids.forEach((id, index) => { const names = this.splitPersonnelNames(namesValue)
if (!options.some(item => item.人员编号 === id)) { normalizedIds.forEach((id, index) => {
if (!options.some(item => String(item.人员编号) === id)) {
options.push({ 人员编号: id, 人员姓名: names[index] || id }) options.push({ 人员编号: id, 人员姓名: names[index] || id })
} }
}) })
}, },
normalizePersonnelIds(value) {
const values = Array.isArray(value) ? value : String(value || '').split(',')
return values.map(item => String(item).trim()).filter(Boolean)
},
splitPersonnelNames(value) {
return String(value || '').split(',').map(item => item.trim()).filter(Boolean)
},
cachePersonnelOptions(rows) {
const nameMap = { ...this.personnelNameMap }
rows.forEach(item => {
const id = String(item.人员编号 || '').trim()
if (id) nameMap[id] = item.人员姓名 || id
})
this.personnelNameMap = nameMap
},
mergePersonnelOptions(currentOptions, rows, selectedIds) {
const selectedSet = new Set(this.normalizePersonnelIds(selectedIds))
const optionMap = new Map()
currentOptions.forEach(item => {
const id = String(item.人员编号 || '').trim()
if (id && selectedSet.has(id)) optionMap.set(id, item)
})
rows.forEach(item => {
const id = String(item.人员编号 || '').trim()
if (id) optionMap.set(id, { ...item, 人员编号: id })
})
return Array.from(optionMap.values())
},
getPersonnelNames(idsValue, fallbackValue) {
const ids = this.normalizePersonnelIds(idsValue)
const fallbackNames = this.splitPersonnelNames(fallbackValue)
return ids.map((id, index) => this.personnelNameMap[id] || fallbackNames[index] || id)
},
formatAssigneeNames(row) {
const names = this.getPersonnelNames(row.指派对象ID, row.指派对象)
return names.length > 0 ? names.join('、') : (row.指派对象 || '')
},
formatMaterialLabel(item) { formatMaterialLabel(item) {
return item.物料名称 ? `${item.物料编码} | ${item.物料名称}` : item.物料编码 return item.物料名称 ? `${item.物料编码} | ${item.物料名称}` : item.物料编码
}, },

View File

@@ -1036,9 +1036,8 @@ export default {
var lastprocess = arr[arr.length - 1] var lastprocess = arr[arr.length - 1]
var arrid= item.TaskAID.split(',') var arrid= item.TaskAID.split(',')
var lastprocessid = arrid[arrid.length - 1] var lastprocessid = arrid[arrid.length - 1]
console.log(item.派工状态)
if(item.派工状态 < 1){ if(item.派工状态 < 1){
console.log(111) return
postB1( postB1(
"/PurchaseRequests", "/PurchaseRequests",
{ {
@@ -1050,7 +1049,7 @@ export default {
"DocDate": this.formatDate(this.currentTime), "DocDate": this.formatDate(this.currentTime),
"DocDueDate": this.formatDate(this.currentTime), "DocDueDate": this.formatDate(this.currentTime),
"TaxDate": this.formatDate(this.currentTime), "TaxDate": this.formatDate(this.currentTime),
"RequriedDate":this.formatDate(this.currentTime), "RequriedDate":this.formatDate(item.计划完成时间),
"Comments": " ", "Comments": " ",
"DocumentLines": [ "DocumentLines": [
{ {