feat: 完善设计报工与研发工时功能
This commit is contained in:
122
db_backups/add_design_report_check_pagination_20260723.sql
Normal file
122
db_backups/add_design_report_check_pagination_20260723.sql
Normal file
@@ -0,0 +1,122 @@
|
||||
USE [YL_MESDB]
|
||||
GO
|
||||
|
||||
SET ANSI_NULLS ON
|
||||
GO
|
||||
|
||||
SET QUOTED_IDENTIFIER ON
|
||||
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'未校验',
|
||||
@当前操作人 nvarchar(100) = N'',
|
||||
@角色编号 nvarchar(100) = N'',
|
||||
@PageCurrent int = 1,
|
||||
@PageSize int = 20,
|
||||
@PageCount int = NULL OUTPUT,
|
||||
@ItemCount int = NULL OUTPUT
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
SET @PageCurrent = CASE WHEN ISNULL(@PageCurrent, 0) < 1 THEN 1 ELSE @PageCurrent END;
|
||||
SET @PageSize = CASE
|
||||
WHEN ISNULL(@PageSize, 0) < 1 THEN 20
|
||||
WHEN @PageSize > 100 THEN 100
|
||||
ELSE @PageSize
|
||||
END;
|
||||
|
||||
DECLARE @开始 datetime = TRY_CONVERT(datetime, NULLIF(@开始日期, N''));
|
||||
DECLARE @结束 datetime = TRY_CONVERT(datetime, NULLIF(@结束日期, N''));
|
||||
DECLARE @当前用户 nvarchar(100) = LTRIM(RTRIM(ISNULL(@当前操作人, 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;
|
||||
|
||||
CREATE TABLE #FilteredRecords
|
||||
(
|
||||
[RID] int NOT NULL PRIMARY KEY
|
||||
);
|
||||
|
||||
INSERT INTO #FilteredRecords ([RID])
|
||||
SELECT r.[RID]
|
||||
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)
|
||||
)
|
||||
AND
|
||||
(
|
||||
@可查看全部 = 1
|
||||
OR
|
||||
(
|
||||
NULLIF(@当前用户, N'') IS NOT NULL
|
||||
AND
|
||||
(
|
||||
LTRIM(RTRIM(ISNULL(t.[创建人], N''))) = @当前用户
|
||||
OR LTRIM(RTRIM(ISNULL(r.[操作人], N''))) = @当前用户
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
SELECT @ItemCount = COUNT(1) FROM #FilteredRecords;
|
||||
SET @PageCount = CASE
|
||||
WHEN @ItemCount = 0 THEN 0
|
||||
ELSE CEILING(CONVERT(decimal(18, 2), @ItemCount) / @PageSize)
|
||||
END;
|
||||
|
||||
SELECT
|
||||
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.[进度说明],
|
||||
r.[备注],
|
||||
t.[单据状态]
|
||||
FROM #FilteredRecords AS f
|
||||
INNER JOIN [dbo].[MES_设计报工_记录] AS r ON f.[RID] = r.[RID]
|
||||
INNER JOIN [dbo].[MES_设计报工_任务] AS t ON r.[DID] = t.[DID]
|
||||
ORDER BY r.[RID] DESC
|
||||
OFFSET (@PageCurrent - 1) * @PageSize ROWS
|
||||
FETCH NEXT @PageSize ROWS ONLY;
|
||||
END
|
||||
GO
|
||||
204
db_backups/add_design_report_task_view_permissions_20260723.sql
Normal file
204
db_backups/add_design_report_task_view_permissions_20260723.sql
Normal file
@@ -0,0 +1,204 @@
|
||||
USE [YL_MESDB];
|
||||
GO
|
||||
|
||||
SET ANSI_NULLS ON;
|
||||
GO
|
||||
SET QUOTED_IDENTIFIER ON;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER PROCEDURE [dbo].[设计报工_任务_查询]
|
||||
@DID int = NULL,
|
||||
@项目号 nvarchar(100) = N'',
|
||||
@物料编码 nvarchar(100) = N'',
|
||||
@图号 nvarchar(100) = N'',
|
||||
@类别 nvarchar(100) = N'',
|
||||
@任务来源 nvarchar(200) = 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'',
|
||||
@角色编号 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''));
|
||||
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;
|
||||
|
||||
SELECT TOP 1000
|
||||
ISNULL(task_notes.[领导批示], N'') AS [领导批示],
|
||||
t.[DID],
|
||||
t.[项目号],
|
||||
t.[物料编码],
|
||||
t.[物料名称],
|
||||
t.[图号],
|
||||
t.[类别],
|
||||
t.[任务来源],
|
||||
t.[任务描述],
|
||||
t.[关联父件物料编码],
|
||||
t.[关联父件物料名称],
|
||||
t.[设计要求],
|
||||
t.[研发立项号],
|
||||
t.[研发目的],
|
||||
t.[对齐可见ID],
|
||||
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 [最后结束时间],
|
||||
ISNULL(progress_notes.[进度说明], N'') AS [进度说明],
|
||||
ISNULL(task_notes.[异常说明], N'') AS [异常说明],
|
||||
ISNULL(task_notes.[奇思妙想], N'') 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
|
||||
OUTER APPLY
|
||||
(
|
||||
SELECT STRING_AGG(
|
||||
CONVERT(nvarchar(max),
|
||||
CONVERT(nvarchar(19), rr3.[结束时间], 120)
|
||||
+ N' '
|
||||
+ COALESCE(NULLIF(LTRIM(RTRIM(rr3.[操作人])), N''), NULLIF(LTRIM(RTRIM(rr3.[操作人ID])), N''), N'未填写编辑人')
|
||||
+ NCHAR(13) + NCHAR(10)
|
||||
+ rr3.[进度说明]),
|
||||
NCHAR(13) + NCHAR(10) + NCHAR(13) + NCHAR(10)
|
||||
) WITHIN GROUP (ORDER BY rr3.[结束时间] DESC, rr3.[RID] DESC) AS [进度说明]
|
||||
FROM [dbo].[MES_设计报工_记录] AS rr3
|
||||
WHERE rr3.[DID] = t.[DID]
|
||||
AND NULLIF(LTRIM(RTRIM(rr3.[进度说明])), N'') IS NOT NULL
|
||||
) AS progress_notes
|
||||
OUTER APPLY
|
||||
(
|
||||
SELECT
|
||||
STRING_AGG(
|
||||
CASE WHEN n.[说明类型] = N'领导批示'
|
||||
THEN CONVERT(nvarchar(max),
|
||||
CONVERT(nvarchar(19), n.[录入时间], 120)
|
||||
+ N' '
|
||||
+ COALESCE(NULLIF(LTRIM(RTRIM(n.[操作人])), N''), NULLIF(LTRIM(RTRIM(n.[操作人ID])), N''), N'未填写编辑人')
|
||||
+ NCHAR(13) + NCHAR(10)
|
||||
+ n.[说明内容]) END,
|
||||
NCHAR(13) + NCHAR(10) + NCHAR(13) + NCHAR(10)
|
||||
) WITHIN GROUP (ORDER BY n.[录入时间] DESC, n.[SID] DESC) AS [领导批示],
|
||||
STRING_AGG(
|
||||
CASE WHEN n.[说明类型] = N'异常说明'
|
||||
THEN CONVERT(nvarchar(max),
|
||||
CONVERT(nvarchar(19), n.[录入时间], 120)
|
||||
+ N' '
|
||||
+ COALESCE(NULLIF(LTRIM(RTRIM(n.[操作人])), N''), NULLIF(LTRIM(RTRIM(n.[操作人ID])), N''), N'未填写编辑人')
|
||||
+ NCHAR(13) + NCHAR(10)
|
||||
+ n.[说明内容]) END,
|
||||
NCHAR(13) + NCHAR(10) + NCHAR(13) + NCHAR(10)
|
||||
) WITHIN GROUP (ORDER BY n.[录入时间] DESC, n.[SID] DESC) AS [异常说明],
|
||||
STRING_AGG(
|
||||
CASE WHEN n.[说明类型] = N'奇思妙想'
|
||||
THEN CONVERT(nvarchar(max),
|
||||
CONVERT(nvarchar(19), n.[录入时间], 120)
|
||||
+ N' '
|
||||
+ COALESCE(NULLIF(LTRIM(RTRIM(n.[操作人])), N''), NULLIF(LTRIM(RTRIM(n.[操作人ID])), N''), N'未填写编辑人')
|
||||
+ NCHAR(13) + NCHAR(10)
|
||||
+ n.[说明内容]) END,
|
||||
NCHAR(13) + NCHAR(10) + NCHAR(13) + NCHAR(10)
|
||||
) WITHIN GROUP (ORDER BY n.[录入时间] DESC, n.[SID] DESC) AS [奇思妙想]
|
||||
FROM [dbo].[MES_设计报工_任务说明] AS n
|
||||
WHERE n.[DID] = t.[DID]
|
||||
) AS task_notes
|
||||
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 t.[关联父件物料编码] LIKE N'%' + @关联父件物料编码 + N'%')
|
||||
AND
|
||||
(
|
||||
ISNULL(@单据状态, N'') = N''
|
||||
OR @单据状态 = N'全部'
|
||||
OR (@单据状态 = N'未完成' AND ISNULL(t.[单据状态], N'') <> N'已完成')
|
||||
OR (@单据状态 <> N'未完成' AND 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))
|
||||
AND
|
||||
(
|
||||
@可查看全部 = 1
|
||||
OR (NULLIF(@当前操作人, N'') IS NOT NULL AND ISNULL(t.[创建人], N'') = @当前操作人)
|
||||
OR
|
||||
(
|
||||
NULLIF(@当前操作人ID, N'') IS NOT NULL
|
||||
AND CHARINDEX(N',' + @当前操作人ID + N',', N',' + ISNULL(t.[对齐可见ID], N'') + N',') > 0
|
||||
)
|
||||
OR
|
||||
(
|
||||
NULLIF(@当前操作人, N'') IS NOT NULL
|
||||
AND CHARINDEX(N',' + @当前操作人 + N',', N',' + ISNULL(t.[对齐可见], N'') + N',') > 0
|
||||
)
|
||||
OR
|
||||
(
|
||||
NULLIF(@当前操作人ID, N'') IS NOT NULL
|
||||
AND CHARINDEX(N',' + @当前操作人ID + N',', N',' + ISNULL(t.[指派对象ID], N'') + N',') > 0
|
||||
)
|
||||
OR
|
||||
(
|
||||
NULLIF(@当前操作人, N'') IS NOT NULL
|
||||
AND CHARINDEX(N',' + @当前操作人 + N',', N',' + ISNULL(t.[指派对象], N'') + N',') > 0
|
||||
)
|
||||
)
|
||||
ORDER BY t.[DID] DESC;
|
||||
END
|
||||
GO
|
||||
197
db_backups/add_research_financial_hours_20260723.sql
Normal file
197
db_backups/add_research_financial_hours_20260723.sql
Normal file
@@ -0,0 +1,197 @@
|
||||
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'',
|
||||
@任务来源 nvarchar(200) = 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 @当前用户 nvarchar(100) = LTRIM(RTRIM(ISNULL(@当前操作人, 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;
|
||||
|
||||
SELECT
|
||||
r.[RID],
|
||||
r.[DID],
|
||||
ISNULL(r.[操作人], N'') AS [操作人],
|
||||
CONVERT(varchar(10), r.[开始时间], 120) AS [工作日期],
|
||||
CONVERT(varchar(19), t.[创建日期], 120) AS [创建日期],
|
||||
ISNULL(t.[类别], N'') AS [类别],
|
||||
ISNULL(t.[任务来源], N'') AS [任务来源],
|
||||
ISNULL(t.[任务描述], N'') AS [任务描述],
|
||||
ISNULL(t.[设计要求], N'') AS [设计要求],
|
||||
ISNULL(t.[对齐可见], N'') AS [对齐可见],
|
||||
ISNULL(t.[指派对象], N'') AS [指派对象],
|
||||
CONVERT(varchar(19), t.[预计开始时间], 120) AS [预计开始时间],
|
||||
CONVERT(varchar(19), t.[预计结束时间], 120) AS [预计结束时间],
|
||||
ISNULL(t.[项目号], N'') AS [项目号],
|
||||
ISNULL(t.[物料编码], N'') AS [物料编码],
|
||||
ISNULL(t.[物料名称], N'') AS [物料名称],
|
||||
ISNULL(t.[图号], N'') AS [图号],
|
||||
ISNULL(t.[关联父件物料编码], N'') AS [关联父件物料编码],
|
||||
ISNULL(t.[关联父件物料名称], N'') AS [关联父件物料名称],
|
||||
ISNULL(t.[研发立项号], N'') AS [研发立项号],
|
||||
ISNULL(t.[研发目的], N'') AS [研发目的],
|
||||
ISNULL(t.[单据状态], N'') AS [任务状态],
|
||||
ISNULL(t.[创建人], N'') AS [创建人],
|
||||
ISNULL(t.[备注], N'') AS [任务备注],
|
||||
CONVERT(varchar(19), r.[开始时间], 120) AS [开始时间],
|
||||
CONVERT(varchar(19), r.[结束时间], 120) AS [结束时间],
|
||||
CAST(1 AS int) AS [报工次数],
|
||||
CAST(ISNULL(r.[工时秒数], 0) / 3600.0 AS decimal(18, 2)) AS [工时小时],
|
||||
CASE WHEN r.[已校验] = 1 THEN N'已校验' ELSE N'未校验' END AS [校验状态],
|
||||
ISNULL(r.[进度说明], N'') AS [进度说明],
|
||||
ISNULL(r.[备注], N'') AS [报工备注]
|
||||
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 (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(@当前用户, N'') IS NOT NULL
|
||||
AND
|
||||
(
|
||||
LTRIM(RTRIM(ISNULL(t.[创建人], N''))) = @当前用户
|
||||
OR LTRIM(RTRIM(ISNULL(r.[操作人], N''))) = @当前用户
|
||||
)
|
||||
)
|
||||
)
|
||||
ORDER BY r.[开始时间] DESC, r.[RID] DESC;
|
||||
END
|
||||
GO
|
||||
|
||||
SET NOCOUNT ON;
|
||||
SET XACT_ABORT ON;
|
||||
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
DECLARE @TargetMenus TABLE
|
||||
(
|
||||
[账号代码] int NOT NULL PRIMARY KEY,
|
||||
[研发管理ID] int NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO @TargetMenus ([账号代码], [研发管理ID])
|
||||
SELECT
|
||||
parent_menu.[账号代码],
|
||||
MIN(parent_menu.[id]) AS [研发管理ID]
|
||||
FROM [dbo].[登录基础数据_二级菜单] AS parent_menu WITH (UPDLOCK, HOLDLOCK)
|
||||
WHERE parent_menu.[pid] = 0
|
||||
AND parent_menu.[是否启用] = 1
|
||||
AND
|
||||
(
|
||||
parent_menu.[title] = N'研发管理'
|
||||
OR parent_menu.[path] = '/ResearchManagement'
|
||||
OR parent_menu.[name] = 'ResearchManagement'
|
||||
)
|
||||
GROUP BY parent_menu.[账号代码];
|
||||
|
||||
UPDATE menu_row
|
||||
SET
|
||||
menu_row.[pid] = target.[研发管理ID],
|
||||
menu_row.[path] = 'DesignReportTask/FinancialHours/index',
|
||||
menu_row.[componet] = '/ProductionManagement/DesignReportTask/FinancialHours/index',
|
||||
menu_row.[redirect] = NULL,
|
||||
menu_row.[name] = 'DesignReportFinancialHours',
|
||||
menu_row.[title] = N'研发财务工时',
|
||||
menu_row.[icon] = 'WhiteCollarBonusesSummary',
|
||||
menu_row.[模块代码] = menu_row.[id],
|
||||
menu_row.[是否启用] = 1,
|
||||
menu_row.[操作时间] = GETDATE()
|
||||
FROM [dbo].[登录基础数据_二级菜单] AS menu_row
|
||||
INNER JOIN @TargetMenus AS target ON target.[账号代码] = menu_row.[账号代码]
|
||||
WHERE
|
||||
menu_row.[path] = 'DesignReportTask/FinancialHours/index'
|
||||
OR menu_row.[componet] = '/ProductionManagement/DesignReportTask/FinancialHours/index'
|
||||
OR menu_row.[name] = 'DesignReportFinancialHours'
|
||||
OR menu_row.[title] = N'研发财务工时';
|
||||
|
||||
INSERT INTO [dbo].[登录基础数据_二级菜单]
|
||||
([id], [pid], [path], [componet], [redirect], [name], [title], [icon], [账号代码], [模块代码], [是否启用], [操作时间])
|
||||
SELECT
|
||||
next_id.[新菜单ID],
|
||||
target.[研发管理ID],
|
||||
'DesignReportTask/FinancialHours/index',
|
||||
'/ProductionManagement/DesignReportTask/FinancialHours/index',
|
||||
NULL,
|
||||
'DesignReportFinancialHours',
|
||||
N'研发财务工时',
|
||||
'WhiteCollarBonusesSummary',
|
||||
target.[账号代码],
|
||||
next_id.[新菜单ID],
|
||||
1,
|
||||
GETDATE()
|
||||
FROM @TargetMenus AS target
|
||||
CROSS APPLY
|
||||
(
|
||||
SELECT ISNULL(MAX(existing.[id]), 0) + 1 AS [新菜单ID]
|
||||
FROM [dbo].[登录基础数据_二级菜单] AS existing WITH (UPDLOCK, HOLDLOCK)
|
||||
WHERE existing.[账号代码] = target.[账号代码]
|
||||
) AS next_id
|
||||
WHERE NOT EXISTS
|
||||
(
|
||||
SELECT 1
|
||||
FROM [dbo].[登录基础数据_二级菜单] AS existing WITH (UPDLOCK, HOLDLOCK)
|
||||
WHERE existing.[账号代码] = target.[账号代码]
|
||||
AND
|
||||
(
|
||||
existing.[path] = 'DesignReportTask/FinancialHours/index'
|
||||
OR existing.[componet] = '/ProductionManagement/DesignReportTask/FinancialHours/index'
|
||||
OR existing.[name] = 'DesignReportFinancialHours'
|
||||
OR existing.[title] = N'研发财务工时'
|
||||
)
|
||||
);
|
||||
|
||||
COMMIT TRANSACTION;
|
||||
|
||||
SELECT
|
||||
menu_row.[id],
|
||||
menu_row.[pid],
|
||||
menu_row.[path],
|
||||
menu_row.[componet],
|
||||
menu_row.[name],
|
||||
menu_row.[title],
|
||||
menu_row.[icon],
|
||||
menu_row.[账号代码],
|
||||
menu_row.[是否启用]
|
||||
FROM [dbo].[登录基础数据_二级菜单] AS menu_row
|
||||
WHERE menu_row.[title] = N'研发财务工时'
|
||||
ORDER BY menu_row.[账号代码], menu_row.[id];
|
||||
GO
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="app-container design-check-page">
|
||||
<el-card>
|
||||
<div class="search-container" @keyup.enter="searchTable">
|
||||
<div class="search-container" @keyup.enter="queryTable">
|
||||
<span class="show-text">任务ID:</span>
|
||||
<el-input v-model="searchForm.did" clearable size="small" style="width: 90px; margin-right: 8px" />
|
||||
<span class="show-text">项目号:</span>
|
||||
@@ -54,8 +54,8 @@
|
||||
<el-option label="已校验" value="已校验" />
|
||||
<el-option label="全部" value="全部" />
|
||||
</el-select>
|
||||
<el-button :loading="loading" icon="el-icon-search" plain size="small" type="primary" @click="searchTable">查询</el-button>
|
||||
<el-button :disabled="!multipleSelection.length" icon="el-icon-check" plain size="small" type="success" @click="batchValidate" style="width: auto">批量校验</el-button>
|
||||
<el-button :loading="loading" icon="el-icon-search" plain size="small" type="primary" @click="queryTable">查询</el-button>
|
||||
<el-button :disabled="!multipleSelection.length" icon="el-icon-check" plain size="small" style="width: auto" type="success" @click="batchValidate">批量校验</el-button>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
@@ -105,6 +105,18 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-bar">
|
||||
<el-pagination
|
||||
:current-page="pageCurrent"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog
|
||||
@@ -157,6 +169,9 @@ export default {
|
||||
multipleSelection: [],
|
||||
projectOptions: [],
|
||||
materialOptions: [],
|
||||
pageCurrent: 1,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
searchForm: {
|
||||
did: '',
|
||||
projectNo: '',
|
||||
@@ -220,22 +235,44 @@ export default {
|
||||
['结束日期', this.searchForm.endDate || ''],
|
||||
['校验状态', this.searchForm.checkStatus || '全部'],
|
||||
['当前操作人', this.currentUserName()],
|
||||
['角色编号', this.currentRoleId()]
|
||||
['角色编号', this.currentRoleId()],
|
||||
['PageCurrent', this.pageCurrent],
|
||||
['PageSize', this.pageSize],
|
||||
['PageCount', '0', 'int', '1'],
|
||||
['ItemCount', '0', 'int', '1']
|
||||
]
|
||||
},
|
||||
queryTable() {
|
||||
this.pageCurrent = 1
|
||||
this.searchTable()
|
||||
},
|
||||
async searchTable() {
|
||||
this.loading = true
|
||||
const data = this.CreateData('11', '设计报工_工时校验_查询', this.buildSearchParams())
|
||||
try {
|
||||
const response = await this.ExecDatabase(data)
|
||||
this.tableData = response.data || []
|
||||
const responseData = response.data || {}
|
||||
this.tableData = Array.isArray(responseData.result) ? responseData.result : []
|
||||
const output = Array.isArray(responseData.output) ? responseData.output[0] || {} : {}
|
||||
this.total = Number(output.ItemCount) || 0
|
||||
} catch (error) {
|
||||
console.error('设计工时校验查询失败:', error)
|
||||
this.tableData = []
|
||||
this.total = 0
|
||||
this.$message.error('查询失败')
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
handleSizeChange(size) {
|
||||
this.pageCurrent = 1
|
||||
this.pageSize = size
|
||||
this.searchTable()
|
||||
},
|
||||
handleCurrentChange(page) {
|
||||
this.pageCurrent = page
|
||||
this.searchTable()
|
||||
},
|
||||
async queryProjects(query) {
|
||||
const data = this.CreateData('11', '设计报工_项目查询', [['过滤', query || '']])
|
||||
try {
|
||||
@@ -312,7 +349,7 @@ export default {
|
||||
return
|
||||
}
|
||||
this.$confirm(`确定批量校验 ${rows.length} 条设计报工记录吗?`, '提示', { type: 'warning' })
|
||||
.then(async () => {
|
||||
.then(async() => {
|
||||
const params = [
|
||||
['RIDs', rows.map(row => row.RID).join(',')],
|
||||
['校验人ID', this.currentUserId()],
|
||||
@@ -374,6 +411,10 @@ export default {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.pagination-bar {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.design-action-buttons {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -0,0 +1,495 @@
|
||||
<template>
|
||||
<div class="app-container financial-hours-page">
|
||||
<el-card>
|
||||
<div class="search-container" @keyup.enter="queryReport">
|
||||
<span class="show-text">开始日期:</span>
|
||||
<el-date-picker v-model="searchForm.startDate" clearable size="small" style="width: 140px; margin-right: 8px" type="date" value-format="yyyy-MM-dd" />
|
||||
<span class="show-text">结束日期:</span>
|
||||
<el-date-picker v-model="searchForm.endDate" clearable size="small" style="width: 140px; margin-right: 8px" type="date" value-format="yyyy-MM-dd" />
|
||||
<span class="show-text">操作人:</span>
|
||||
<el-input v-model="searchForm.operator" clearable size="small" style="width: 120px; margin-right: 8px" />
|
||||
<span class="show-text">项目号:</span>
|
||||
<el-select
|
||||
v-model="searchForm.projectNo"
|
||||
clearable
|
||||
filterable
|
||||
remote
|
||||
:remote-method="queryProjects"
|
||||
size="small"
|
||||
style="width: 170px; margin-right: 8px"
|
||||
@clear="loadDefaultProjectOptions"
|
||||
@visible-change="handleProjectVisibleChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in projectOptions"
|
||||
:key="item.项目号"
|
||||
:label="formatProjectLabel(item)"
|
||||
:value="item.项目号"
|
||||
/>
|
||||
</el-select>
|
||||
<span class="show-text">物料编码:</span>
|
||||
<el-select
|
||||
v-model="searchForm.itemCode"
|
||||
clearable
|
||||
filterable
|
||||
remote
|
||||
:remote-method="queryMaterialOptions"
|
||||
size="small"
|
||||
style="width: 190px; margin-right: 8px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in materialOptions"
|
||||
:key="item.物料编码"
|
||||
:label="formatMaterialLabel(item)"
|
||||
:value="item.物料编码"
|
||||
/>
|
||||
</el-select>
|
||||
<span class="show-text">类别:</span>
|
||||
<el-input v-model="searchForm.category" clearable size="small" style="width: 110px; margin-right: 8px" />
|
||||
<span class="show-text">任务来源:</span>
|
||||
<el-input v-model="searchForm.taskSource" clearable size="small" style="width: 120px; margin-right: 8px" />
|
||||
<span class="show-text">研发立项号:</span>
|
||||
<el-input v-model="searchForm.rdProjectNo" clearable size="small" style="width: 130px; margin-right: 8px" />
|
||||
<span class="show-text">任务ID:</span>
|
||||
<el-input v-model="searchForm.did" clearable size="small" style="width: 90px; margin-right: 8px" />
|
||||
<el-button :loading="loading" icon="el-icon-search" plain size="small" type="primary" @click="queryReport">查询</el-button>
|
||||
<el-button
|
||||
:disabled="loading || currentTableData.length === 0"
|
||||
:loading="exporting"
|
||||
icon="el-icon-download"
|
||||
plain
|
||||
size="small"
|
||||
type="success"
|
||||
@click="exportToExcel"
|
||||
>导出</el-button>
|
||||
</div>
|
||||
|
||||
<el-tabs v-model="activeTab" class="report-tabs">
|
||||
<el-tab-pane label="作业者工时" name="operator">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="operatorTableData"
|
||||
border
|
||||
default-expand-all
|
||||
:empty-text="emptyText"
|
||||
height="68vh"
|
||||
row-key="id"
|
||||
size="mini"
|
||||
style="width: 100%"
|
||||
:tree-props="{ children: 'children' }"
|
||||
>
|
||||
<el-table-column fixed label="层级" width="150">
|
||||
<template slot-scope="scope">
|
||||
<span :class="{ 'bold-text': scope.row.Level < 3 }">{{ getLevelLabel(scope.row, 'operator') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-for="column in operatorColumns"
|
||||
:key="`operator-${column.prop}`"
|
||||
:align="column.align"
|
||||
:label="column.label"
|
||||
:prop="column.prop"
|
||||
show-overflow-tooltip
|
||||
:width="column.width"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span :class="{ 'bold-text': scope.row.Level < 3 }">{{ formatCell(scope.row, column.prop) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="任务工时" name="task">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="taskTableData"
|
||||
border
|
||||
default-expand-all
|
||||
:empty-text="emptyText"
|
||||
height="68vh"
|
||||
row-key="id"
|
||||
size="mini"
|
||||
style="width: 100%"
|
||||
:tree-props="{ children: 'children' }"
|
||||
>
|
||||
<el-table-column fixed label="层级" width="100">
|
||||
<template slot-scope="scope">
|
||||
<span :class="{ 'bold-text': scope.row.Level < 3 }">{{ getLevelLabel(scope.row, 'task') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-for="column in taskColumns"
|
||||
:key="`task-${column.prop}`"
|
||||
:align="column.align"
|
||||
:label="column.label"
|
||||
:prop="column.prop"
|
||||
show-overflow-tooltip
|
||||
:width="column.width"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span :class="{ 'bold-text': scope.row.Level < 3 }">{{ formatCell(scope.row, column.prop) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<div class="summary-footer">
|
||||
<span>总工时:<strong>{{ totalHours }}</strong> 小时</span>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as XLSX from 'xlsx'
|
||||
|
||||
export default {
|
||||
name: 'DesignReportFinancialHours',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
exporting: false,
|
||||
hasSearched: false,
|
||||
activeTab: 'operator',
|
||||
operatorTableData: [],
|
||||
taskTableData: [],
|
||||
projectOptions: [],
|
||||
materialOptions: [],
|
||||
reportColumns: [
|
||||
{ prop: '操作人', label: '操作人', width: 110, align: 'left', exportWidth: 16 },
|
||||
{ prop: '工作日期', label: '工作日期', width: 110, align: 'center', exportWidth: 14 },
|
||||
{ prop: 'RID', label: 'RID', width: 70, align: 'center', exportWidth: 10 },
|
||||
{ prop: 'DID', label: 'DID', width: 70, align: 'center', exportWidth: 10 },
|
||||
{ prop: '创建日期', label: '创建日期', width: 155, align: 'center', exportWidth: 21 },
|
||||
{ prop: '类别', label: '类别', width: 110, align: 'left', exportWidth: 16 },
|
||||
{ prop: '任务来源', label: '任务来源', width: 150, align: 'left', exportWidth: 22 },
|
||||
{ prop: '任务描述', label: '任务描述', width: 260, align: 'left', exportWidth: 36 },
|
||||
{ prop: '设计要求', label: '设计要求', width: 260, align: 'left', exportWidth: 36 },
|
||||
{ prop: '对齐可见', label: '对其可见', width: 180, align: 'left', exportWidth: 24 },
|
||||
{ prop: '指派对象', label: '指派对象', width: 180, align: 'left', exportWidth: 24 },
|
||||
{ prop: '预计开始时间', label: '预计开始时间', width: 155, align: 'center', exportWidth: 21 },
|
||||
{ prop: '预计结束时间', label: '预计结束时间', width: 155, align: 'center', exportWidth: 21 },
|
||||
{ prop: '项目号', label: '项目号', width: 130, align: 'left', exportWidth: 18 },
|
||||
{ prop: '物料编码', label: '物料编码', width: 180, align: 'left', exportWidth: 24 },
|
||||
{ prop: '物料名称', label: '物料名称', width: 200, align: 'left', exportWidth: 28 },
|
||||
{ prop: '图号', label: '图号', width: 140, align: 'left', exportWidth: 20 },
|
||||
{ prop: '关联父件物料编码', label: '父件物料编码', width: 180, align: 'left', exportWidth: 24 },
|
||||
{ prop: '关联父件物料名称', label: '父件物料名称', width: 200, align: 'left', exportWidth: 28 },
|
||||
{ prop: '研发立项号', label: '研发立项号', width: 140, align: 'left', exportWidth: 20 },
|
||||
{ prop: '研发目的', label: '研发目的', width: 260, align: 'left', exportWidth: 36 },
|
||||
{ prop: '任务状态', label: '任务状态', width: 100, align: 'center', exportWidth: 14 },
|
||||
{ prop: '创建人', label: '创建人', width: 110, align: 'left', exportWidth: 16 },
|
||||
{ prop: '任务备注', label: '任务备注', width: 220, align: 'left', exportWidth: 30 },
|
||||
{ prop: '开始时间', label: '报工开始时间', width: 155, align: 'center', exportWidth: 21 },
|
||||
{ prop: '结束时间', label: '报工结束时间', width: 155, align: 'center', exportWidth: 21 },
|
||||
{ prop: '报工次数', label: '报工次数', width: 90, align: 'center', exportWidth: 12 },
|
||||
{ prop: '工时小时', label: '工时(h)', width: 90, align: 'right', exportWidth: 12 },
|
||||
{ prop: '校验状态', label: '校验状态', width: 100, align: 'center', exportWidth: 14 },
|
||||
{ prop: '进度说明', label: '进度说明', width: 240, align: 'left', exportWidth: 34 },
|
||||
{ prop: '报工备注', label: '报工备注', width: 220, align: 'left', exportWidth: 30 }
|
||||
],
|
||||
searchForm: {
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
operator: '',
|
||||
projectNo: '',
|
||||
itemCode: '',
|
||||
category: '',
|
||||
taskSource: '',
|
||||
rdProjectNo: '',
|
||||
did: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentTableData() {
|
||||
return this.activeTab === 'task' ? this.taskTableData : this.operatorTableData
|
||||
},
|
||||
operatorColumns() {
|
||||
return this.orderColumns(['操作人', '工作日期', 'RID', 'DID'])
|
||||
},
|
||||
taskColumns() {
|
||||
return this.orderColumns(['DID', '操作人', '工作日期', 'RID'])
|
||||
},
|
||||
totalHours() {
|
||||
const total = this.currentTableData.reduce((sum, row) => sum + (Number(row.工时小时) || 0), 0)
|
||||
return total.toFixed(2)
|
||||
},
|
||||
emptyText() {
|
||||
return this.hasSearched ? '暂无数据' : '请设置查询条件后点击查询'
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadDefaultProjectOptions()
|
||||
this.loadDefaultMaterialOptions()
|
||||
},
|
||||
methods: {
|
||||
orderColumns(leadingProps) {
|
||||
const leadingColumns = leadingProps.map(prop => this.reportColumns.find(column => column.prop === prop))
|
||||
return leadingColumns.concat(this.reportColumns.filter(column => !leadingProps.includes(column.prop)))
|
||||
},
|
||||
loadDefaultProjectOptions() {
|
||||
this.queryProjects('')
|
||||
},
|
||||
loadDefaultMaterialOptions() {
|
||||
this.queryMaterialOptions('')
|
||||
},
|
||||
handleProjectVisibleChange(visible) {
|
||||
if (visible && this.projectOptions.length === 0) this.loadDefaultProjectOptions()
|
||||
},
|
||||
buildSearchParams() {
|
||||
return [
|
||||
['开始日期', this.searchForm.startDate || ''],
|
||||
['结束日期', this.searchForm.endDate || ''],
|
||||
['操作人', this.searchForm.operator || ''],
|
||||
['项目号', this.searchForm.projectNo || ''],
|
||||
['物料编码', this.searchForm.itemCode || ''],
|
||||
['类别', this.searchForm.category || ''],
|
||||
['任务来源', this.searchForm.taskSource || ''],
|
||||
['研发立项号', this.searchForm.rdProjectNo || ''],
|
||||
['DID', this.searchForm.did || 0],
|
||||
['当前操作人', this.currentUserName()],
|
||||
['角色编号', this.currentRoleId()]
|
||||
]
|
||||
},
|
||||
async queryReport() {
|
||||
this.hasSearched = true
|
||||
this.loading = true
|
||||
const data = this.CreateData('11', '设计报工_研发财务工时_查询', this.buildSearchParams())
|
||||
try {
|
||||
const response = await this.ExecDatabase(data)
|
||||
const rows = Array.isArray(response.data) ? response.data.map(row => ({ ...row })) : []
|
||||
this.operatorTableData = this.buildOperatorTree(rows)
|
||||
this.taskTableData = this.buildTaskTree(rows)
|
||||
} catch (error) {
|
||||
console.error('研发财务工时查询失败:', error)
|
||||
this.operatorTableData = []
|
||||
this.taskTableData = []
|
||||
this.$message.error('查询失败')
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
buildOperatorTree(rows) {
|
||||
const operatorGroups = this.groupBy(rows, row => row.操作人 || '未填写操作人')
|
||||
return Array.from(operatorGroups.entries()).map(([operator, operatorRows]) => {
|
||||
const personId = `p-${operator}`
|
||||
const dateGroups = this.groupBy(operatorRows, row => row.工作日期 || '未填写日期')
|
||||
const children = Array.from(dateGroups.entries()).map(([workDate, dateRows]) => {
|
||||
const dateId = `${personId}-d-${workDate}`
|
||||
return this.createSummaryRow(dateRows, {
|
||||
Level: 2,
|
||||
id: dateId,
|
||||
parentId: personId,
|
||||
操作人: operator,
|
||||
工作日期: workDate,
|
||||
children: dateRows.map(row => ({
|
||||
...row,
|
||||
Level: 3,
|
||||
id: `${dateId}-r-${row.RID}`,
|
||||
parentId: dateId
|
||||
}))
|
||||
})
|
||||
})
|
||||
return this.createSummaryRow(operatorRows, {
|
||||
Level: 1,
|
||||
id: personId,
|
||||
parentId: '',
|
||||
操作人: operator,
|
||||
children
|
||||
})
|
||||
})
|
||||
},
|
||||
buildTaskTree(rows) {
|
||||
const taskGroups = this.groupBy(rows, row => String(row.DID || '未填写任务'))
|
||||
return Array.from(taskGroups.entries()).map(([did, taskRows]) => {
|
||||
const taskId = `t-${did}`
|
||||
const taskMetadata = this.pickTaskMetadata(taskRows[0] || {})
|
||||
const operatorGroups = this.groupBy(taskRows, row => row.操作人 || '未填写操作人')
|
||||
const children = Array.from(operatorGroups.entries()).map(([operator, operatorRows]) => {
|
||||
const operatorId = `${taskId}-o-${operator}`
|
||||
return this.createSummaryRow(operatorRows, {
|
||||
...taskMetadata,
|
||||
Level: 2,
|
||||
id: operatorId,
|
||||
parentId: taskId,
|
||||
DID: did,
|
||||
操作人: operator,
|
||||
children: operatorRows.map(row => ({
|
||||
...row,
|
||||
Level: 3,
|
||||
id: `${operatorId}-r-${row.RID}`,
|
||||
parentId: operatorId
|
||||
}))
|
||||
})
|
||||
})
|
||||
return this.createSummaryRow(taskRows, {
|
||||
...taskMetadata,
|
||||
Level: 1,
|
||||
id: taskId,
|
||||
parentId: '',
|
||||
DID: did,
|
||||
children
|
||||
})
|
||||
})
|
||||
},
|
||||
groupBy(rows, keyGetter) {
|
||||
return rows.reduce((groups, row) => {
|
||||
const key = keyGetter(row)
|
||||
if (!groups.has(key)) groups.set(key, [])
|
||||
groups.get(key).push(row)
|
||||
return groups
|
||||
}, new Map())
|
||||
},
|
||||
pickTaskMetadata(row) {
|
||||
const props = [
|
||||
'DID', '创建日期', '类别', '任务来源', '任务描述', '设计要求', '对齐可见', '指派对象',
|
||||
'预计开始时间', '预计结束时间', '项目号', '物料编码', '物料名称', '图号',
|
||||
'关联父件物料编码', '关联父件物料名称', '研发立项号', '研发目的', '任务状态', '创建人', '任务备注'
|
||||
]
|
||||
return props.reduce((result, prop) => {
|
||||
result[prop] = row[prop]
|
||||
return result
|
||||
}, {})
|
||||
},
|
||||
createSummaryRow(rows, values) {
|
||||
const startTimes = rows.map(row => row.开始时间).filter(Boolean).sort()
|
||||
const endTimes = rows.map(row => row.结束时间).filter(Boolean).sort()
|
||||
const checkedCount = rows.filter(row => row.校验状态 === '已校验').length
|
||||
return {
|
||||
...values,
|
||||
RID: '',
|
||||
开始时间: startTimes[0] || '',
|
||||
结束时间: endTimes[endTimes.length - 1] || '',
|
||||
报工次数: rows.length,
|
||||
工时小时: rows.reduce((sum, row) => sum + (Number(row.工时小时) || 0), 0),
|
||||
校验状态: checkedCount === rows.length ? '已校验' : (checkedCount === 0 ? '未校验' : '部分校验'),
|
||||
进度说明: '',
|
||||
报工备注: ''
|
||||
}
|
||||
},
|
||||
getLevelLabel(row, tabName) {
|
||||
if (row.Level === 3) return '报工明细'
|
||||
if (tabName === 'operator') return row.Level === 1 ? '作业者汇总' : '日期汇总'
|
||||
return row.Level === 1 ? '任务汇总' : '作业者汇总'
|
||||
},
|
||||
formatCell(row, prop) {
|
||||
if (prop === '工时小时') return this.formatHours(row[prop])
|
||||
const value = row[prop]
|
||||
return value === null || value === undefined ? '' : value
|
||||
},
|
||||
exportToExcel() {
|
||||
if (this.currentTableData.length === 0) {
|
||||
this.$message.warning('没有数据可导出')
|
||||
return
|
||||
}
|
||||
this.exporting = true
|
||||
try {
|
||||
const tabName = this.activeTab
|
||||
const reportName = tabName === 'task' ? '任务工时' : '作业者工时'
|
||||
const columns = tabName === 'task' ? this.taskColumns : this.operatorColumns
|
||||
const exportData = this.flattenTree(this.currentTableData).map(row => {
|
||||
const exportRow = { 层级: this.getLevelLabel(row, tabName) }
|
||||
columns.forEach(column => {
|
||||
exportRow[column.label] = this.formatCell(row, column.prop)
|
||||
})
|
||||
return exportRow
|
||||
})
|
||||
const workbook = XLSX.utils.book_new()
|
||||
const worksheet = XLSX.utils.json_to_sheet(exportData)
|
||||
worksheet['!cols'] = [{ wch: 14 }, ...columns.map(column => ({ wch: column.exportWidth || 16 }))]
|
||||
worksheet['!autofilter'] = { ref: worksheet['!ref'] }
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet, reportName)
|
||||
XLSX.writeFile(workbook, `研发财务${reportName}_${this.formatDateForFileName(new Date())}.xlsx`)
|
||||
this.$message.success('导出成功')
|
||||
} catch (error) {
|
||||
console.error('研发财务工时导出失败:', error)
|
||||
this.$message.error('导出失败')
|
||||
} finally {
|
||||
this.exporting = false
|
||||
}
|
||||
},
|
||||
flattenTree(rows) {
|
||||
return rows.reduce((result, row) => {
|
||||
result.push(row)
|
||||
if (row.children && row.children.length > 0) result.push(...this.flattenTree(row.children))
|
||||
return result
|
||||
}, [])
|
||||
},
|
||||
formatHours(value) {
|
||||
if (value === null || value === undefined || value === '') return ''
|
||||
const numberValue = Number(value)
|
||||
return Number.isNaN(numberValue) ? '' : numberValue.toFixed(2)
|
||||
},
|
||||
formatDateForFileName(date) {
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
const hours = String(date.getHours()).padStart(2, '0')
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0')
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0')
|
||||
return `${year}${month}${day}_${hours}${minutes}${seconds}`
|
||||
},
|
||||
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 = []
|
||||
}
|
||||
},
|
||||
formatMaterialLabel(item) {
|
||||
return item.物料名称 ? `${item.物料编码} | ${item.物料名称}` : item.物料编码
|
||||
},
|
||||
formatProjectLabel(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) || ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.financial-hours-page {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
line-height: 34px;
|
||||
}
|
||||
|
||||
.show-text {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.bold-text {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.report-tabs {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.summary-footer {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
text-align: right;
|
||||
color: #303133;
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="app-container design-hours-report-page">
|
||||
<el-card>
|
||||
<div class="search-container" @keyup.enter="searchTable">
|
||||
<div class="search-container" @keyup.enter="queryReport">
|
||||
<span class="show-text">开始日期:</span>
|
||||
<el-date-picker
|
||||
v-model="searchForm.startDate"
|
||||
@@ -62,7 +62,7 @@
|
||||
<el-input v-model="searchForm.category" clearable size="small" style="width: 120px; margin-right: 8px" />
|
||||
<span class="show-text">任务ID:</span>
|
||||
<el-input v-model="searchForm.did" clearable size="small" style="width: 90px; margin-right: 8px" />
|
||||
<el-button :loading="loading" icon="el-icon-search" plain size="small" type="primary" @click="searchTable">查询</el-button>
|
||||
<el-button :loading="loading" icon="el-icon-search" plain size="small" type="primary" @click="queryReport">查询</el-button>
|
||||
<el-button
|
||||
:disabled="loading || currentTableData.length === 0"
|
||||
:loading="exporting"
|
||||
@@ -169,6 +169,7 @@ export default {
|
||||
return {
|
||||
loading: false,
|
||||
exporting: false,
|
||||
hasSearched: false,
|
||||
activeTab: 'operator',
|
||||
operatorTableData: [],
|
||||
taskTableData: [],
|
||||
@@ -197,7 +198,6 @@ export default {
|
||||
created() {
|
||||
this.loadDefaultProjectOptions()
|
||||
this.loadDefaultMaterialOptions()
|
||||
this.searchTable()
|
||||
},
|
||||
methods: {
|
||||
loadDefaultProjectOptions() {
|
||||
@@ -224,6 +224,10 @@ export default {
|
||||
['角色编号', this.currentRoleId()]
|
||||
]
|
||||
},
|
||||
queryReport() {
|
||||
this.hasSearched = true
|
||||
this.searchTable()
|
||||
},
|
||||
async searchTable() {
|
||||
this.loading = true
|
||||
const isTaskReport = this.activeTab === 'task'
|
||||
@@ -402,7 +406,7 @@ export default {
|
||||
return description ? `DID ${row.DID} | ${description}` : `DID ${row.DID}`
|
||||
},
|
||||
handleTabClick() {
|
||||
this.searchTable()
|
||||
if (this.hasSearched) this.searchTable()
|
||||
},
|
||||
formatHours(value) {
|
||||
if (value === null || value === undefined || value === '') return ''
|
||||
|
||||
@@ -81,18 +81,18 @@
|
||||
v-loading="loading"
|
||||
class="design-data-table"
|
||||
:data="tableData"
|
||||
:cell-class-name="getThreeLineCellClassName"
|
||||
border
|
||||
height="74vh"
|
||||
highlight-current-row
|
||||
size="mini"
|
||||
style="width: 100%; margin-top: 12px"
|
||||
@cell-mouse-enter="showThreeLineCellTooltip"
|
||||
@cell-mouse-leave="scheduleHideThreeLineCellTooltip"
|
||||
>
|
||||
<el-table-column align="left" fixed label="领导批示" prop="领导批示" width="360">
|
||||
<el-table-column align="left" fixed label="领导批示" prop="领导批示" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip :disabled="!scope.row.领导批示" effect="dark" placement="top" :open-delay="300">
|
||||
<div slot="content" class="note-tooltip-content">{{ scope.row.领导批示 }}</div>
|
||||
<div class="note-history">{{ scope.row.领导批示 }}</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" fixed label="DID" prop="DID" width="90" />
|
||||
@@ -108,26 +108,17 @@
|
||||
<el-table-column align="center" label="预计结束" prop="预计结束时间" width="180" />
|
||||
<el-table-column align="left" label="进度说明" prop="进度说明" width="360">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip :disabled="!scope.row.进度说明" effect="dark" placement="top" :open-delay="300">
|
||||
<div slot="content" class="note-tooltip-content">{{ scope.row.进度说明 }}</div>
|
||||
<div class="note-history">{{ scope.row.进度说明 }}</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" label="异常说明" prop="异常说明" width="360">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip :disabled="!scope.row.异常说明" effect="dark" placement="top" :open-delay="300">
|
||||
<div slot="content" class="note-tooltip-content">{{ scope.row.异常说明 }}</div>
|
||||
<div class="note-history">{{ scope.row.异常说明 }}</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" label="奇思妙想" prop="奇思妙想" width="360">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip :disabled="!scope.row.奇思妙想" effect="dark" placement="top" :open-delay="300">
|
||||
<div slot="content" class="note-tooltip-content">{{ scope.row.奇思妙想 }}</div>
|
||||
<div class="note-history">{{ scope.row.奇思妙想 }}</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" label="项目号" prop="项目号" width="150" show-overflow-tooltip />
|
||||
@@ -148,22 +139,38 @@
|
||||
<el-table-column align="left" label="备注" prop="备注" width="240" show-overflow-tooltip />
|
||||
<el-table-column align="center" label="最后开始" prop="最后开始时间" width="180" />
|
||||
<el-table-column align="center" label="最后结束" prop="最后结束时间" width="180" />
|
||||
<el-table-column align="center" fixed="right" label="操作" width="640">
|
||||
<el-table-column align="center" fixed="right" label="操作" width="200">
|
||||
<template slot-scope="scope">
|
||||
<div class="design-action-buttons">
|
||||
<el-button type="text" size="mini" :disabled="actionLoading || !canStart(scope.row)" @click="startTask(scope.row)">开始</el-button>
|
||||
<el-button type="text" size="mini" :disabled="!canEnd(scope.row)" @click="endTask(scope.row)">结束</el-button>
|
||||
<el-button v-if="canUseLeaderInstruction" type="text" size="mini" @click="openNoteDialog(scope.row, '领导批示')">领导批示</el-button>
|
||||
<el-button type="text" size="mini" @click="openNoteDialog(scope.row, '异常说明')">异常说明</el-button>
|
||||
<el-button type="text" size="mini" @click="openNoteDialog(scope.row, '奇思妙想')">奇思妙想</el-button>
|
||||
<el-button type="text" size="mini" icon="el-icon-upload2" @click="openAttachments(scope.row, 'upload')">上传附件</el-button>
|
||||
<el-button type="text" size="mini" icon="el-icon-view" @click="openAttachments(scope.row, 'view')">查看附件</el-button>
|
||||
<el-dropdown class="design-action-more" trigger="click">
|
||||
<el-button type="text" size="mini">
|
||||
更多<i class="el-icon-arrow-down el-icon--right" />
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item icon="el-icon-warning-outline" @click.native="openNoteDialog(scope.row, '异常说明')">异常说明</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-s-opportunity" @click.native="openNoteDialog(scope.row, '奇思妙想')">奇思妙想</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-upload2" @click.native="openAttachments(scope.row, 'upload')">上传附件</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-view" @click.native="openAttachments(scope.row, 'view')">查看附件</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<div
|
||||
v-show="tableCellTooltip.visible"
|
||||
class="table-cell-full-tooltip"
|
||||
:style="tableCellTooltipStyle"
|
||||
role="tooltip"
|
||||
@mouseenter="keepThreeLineCellTooltipOpen"
|
||||
@mouseleave="hideThreeLineCellTooltip"
|
||||
>{{ tableCellTooltip.text }}</div>
|
||||
|
||||
<el-dialog
|
||||
:visible.sync="endDialogVisible"
|
||||
title="结束报工"
|
||||
@@ -237,12 +244,14 @@
|
||||
|
||||
<script>
|
||||
import TaskAttachments from '../components/TaskAttachments'
|
||||
import threeLineTableTooltip from '../mixins/threeLineTableTooltip'
|
||||
|
||||
const AUTO_REFRESH_INTERVAL = 5 * 60 * 1000
|
||||
|
||||
export default {
|
||||
name: 'DesignReportWork',
|
||||
components: { TaskAttachments },
|
||||
mixins: [threeLineTableTooltip],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
@@ -348,7 +357,8 @@ export default {
|
||||
['预计结束时间_End', ''],
|
||||
['单据状态', this.searchForm.status || ''],
|
||||
['当前操作人ID', this.currentUserId()],
|
||||
['当前操作人', this.currentUserName()]
|
||||
['当前操作人', this.currentUserName()],
|
||||
['角色编号', this.currentRoleId()]
|
||||
]
|
||||
},
|
||||
async searchTable(options = {}) {
|
||||
@@ -503,7 +513,8 @@ export default {
|
||||
['预计结束时间_End', ''],
|
||||
['单据状态', ''],
|
||||
['当前操作人ID', this.currentUserId()],
|
||||
['当前操作人', this.currentUserName()]
|
||||
['当前操作人', this.currentUserName()],
|
||||
['角色编号', this.currentRoleId()]
|
||||
]
|
||||
const data = this.CreateData('11', '设计报工_任务_查询', params)
|
||||
try {
|
||||
@@ -536,7 +547,8 @@ export default {
|
||||
['预计结束时间_End', ''],
|
||||
['单据状态', ''],
|
||||
['当前操作人ID', this.currentUserId()],
|
||||
['当前操作人', this.currentUserName()]
|
||||
['当前操作人', this.currentUserName()],
|
||||
['角色编号', this.currentRoleId()]
|
||||
]
|
||||
const data = this.CreateData('11', '设计报工_任务_查询', params)
|
||||
try {
|
||||
@@ -616,13 +628,15 @@ export default {
|
||||
}
|
||||
|
||||
.design-action-buttons {
|
||||
display: inline-flex;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
grid-auto-rows: 32px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: nowrap;
|
||||
gap: 10px;
|
||||
gap: 8px 1px;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
height: 72px;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.design-action-buttons ::v-deep .el-button {
|
||||
@@ -636,6 +650,14 @@ export default {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.design-action-more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.design-data-table ::v-deep .el-table__header th {
|
||||
height: 48px;
|
||||
padding: 8px 0;
|
||||
@@ -644,7 +666,8 @@ export default {
|
||||
|
||||
.design-data-table ::v-deep .el-table__row,
|
||||
.design-data-table ::v-deep .el-table__body td {
|
||||
height: 108px;
|
||||
height: 108px !important;
|
||||
max-height: 108px;
|
||||
}
|
||||
|
||||
.design-data-table ::v-deep .el-table__body td {
|
||||
@@ -656,11 +679,15 @@ export default {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.design-data-table ::v-deep .el-table__body .cell,
|
||||
.design-data-table ::v-deep .el-table__body .cell.el-tooltip {
|
||||
.design-data-table ::v-deep .el-table__body .three-line-table-cell .cell {
|
||||
display: -webkit-box !important;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
white-space: normal !important;
|
||||
overflow: visible;
|
||||
text-overflow: clip;
|
||||
height: 72px;
|
||||
max-height: 72px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
}
|
||||
@@ -672,20 +699,45 @@ export default {
|
||||
}
|
||||
|
||||
.note-history {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
width: 100%;
|
||||
height: 72px;
|
||||
min-height: 72px;
|
||||
max-height: 72px;
|
||||
line-height: 24px;
|
||||
white-space: pre-line;
|
||||
overflow: visible;
|
||||
white-space: pre-wrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.note-tooltip-content {
|
||||
max-width: 520px;
|
||||
.table-cell-full-tooltip {
|
||||
position: fixed;
|
||||
z-index: 4000;
|
||||
width: max-content;
|
||||
max-width: 600px;
|
||||
min-width: 80px;
|
||||
max-height: 60vh;
|
||||
padding: 10px 12px;
|
||||
color: #fff;
|
||||
background: #303133;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.18);
|
||||
pointer-events: auto;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
white-space: pre-line;
|
||||
white-space: pre-wrap;
|
||||
overflow-y: auto;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
@media (max-width: 624px) {
|
||||
.table-cell-full-tooltip {
|
||||
max-width: calc(100vw - 24px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -114,18 +114,18 @@
|
||||
v-loading="loading"
|
||||
class="design-data-table"
|
||||
:data="tableData"
|
||||
:cell-class-name="getThreeLineCellClassName"
|
||||
border
|
||||
height="70vh"
|
||||
highlight-current-row
|
||||
size="mini"
|
||||
style="width: 100%; margin-top: 12px"
|
||||
@cell-mouse-enter="showThreeLineCellTooltip"
|
||||
@cell-mouse-leave="scheduleHideThreeLineCellTooltip"
|
||||
>
|
||||
<el-table-column align="left" fixed label="领导批示" prop="领导批示" width="360">
|
||||
<el-table-column align="left" fixed label="领导批示" prop="领导批示" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip :disabled="!scope.row.领导批示" effect="dark" placement="top" :open-delay="300">
|
||||
<div slot="content" class="note-tooltip-content">{{ scope.row.领导批示 }}</div>
|
||||
<div class="note-history">{{ scope.row.领导批示 }}</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" fixed label="DID" prop="DID" width="90" />
|
||||
@@ -145,26 +145,17 @@
|
||||
<el-table-column align="center" label="预计结束" prop="预计结束时间" width="180" />
|
||||
<el-table-column align="left" label="进度说明" prop="进度说明" width="360">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip :disabled="!scope.row.进度说明" effect="dark" placement="top" :open-delay="300">
|
||||
<div slot="content" class="note-tooltip-content">{{ scope.row.进度说明 }}</div>
|
||||
<div class="note-history">{{ scope.row.进度说明 }}</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" label="异常说明" prop="异常说明" width="360">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip :disabled="!scope.row.异常说明" effect="dark" placement="top" :open-delay="300">
|
||||
<div slot="content" class="note-tooltip-content">{{ scope.row.异常说明 }}</div>
|
||||
<div class="note-history">{{ scope.row.异常说明 }}</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" label="奇思妙想" prop="奇思妙想" width="360">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip :disabled="!scope.row.奇思妙想" effect="dark" placement="top" :open-delay="300">
|
||||
<div slot="content" class="note-tooltip-content">{{ scope.row.奇思妙想 }}</div>
|
||||
<div class="note-history">{{ scope.row.奇思妙想 }}</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" label="项目号" prop="项目号" width="150" show-overflow-tooltip />
|
||||
@@ -185,21 +176,37 @@
|
||||
<el-table-column align="center" label="创建日期" prop="创建日期" width="180" />
|
||||
<el-table-column align="left" label="创建人" prop="创建人" width="140" show-overflow-tooltip />
|
||||
<el-table-column align="left" label="备注" prop="备注" width="240" show-overflow-tooltip />
|
||||
<el-table-column align="center" fixed="right" label="操作" width="540">
|
||||
<el-table-column align="center" fixed="right" label="操作" width="200">
|
||||
<template slot-scope="scope">
|
||||
<div class="design-action-buttons">
|
||||
<el-button type="text" size="mini" @click="openEdit(scope.row)">编辑</el-button>
|
||||
<el-button type="text" size="mini" :disabled="actionLoading || !canComplete(scope.row)" @click="completeTask(scope.row)">完成</el-button>
|
||||
<el-button v-if="canUseLeaderInstruction" type="text" size="mini" @click="openNoteDialog(scope.row)">领导批示</el-button>
|
||||
<el-button type="text" size="mini" icon="el-icon-upload2" @click="openAttachments(scope.row, 'upload')">上传附件</el-button>
|
||||
<el-button type="text" size="mini" icon="el-icon-view" @click="openAttachments(scope.row, 'view')">查看附件</el-button>
|
||||
<el-button type="text" size="mini" class="danger-action" @click="deleteTask(scope.row)">删除</el-button>
|
||||
<el-dropdown class="design-action-more" trigger="click">
|
||||
<el-button type="text" size="mini">
|
||||
更多<i class="el-icon-arrow-down el-icon--right" />
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item icon="el-icon-upload2" @click.native="openAttachments(scope.row, 'upload')">上传附件</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-view" @click.native="openAttachments(scope.row, 'view')">查看附件</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-delete" class="danger-action" @click.native="deleteTask(scope.row)">删除</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<div
|
||||
v-show="tableCellTooltip.visible"
|
||||
class="table-cell-full-tooltip"
|
||||
:style="tableCellTooltipStyle"
|
||||
role="tooltip"
|
||||
@mouseenter="keepThreeLineCellTooltipOpen"
|
||||
@mouseleave="hideThreeLineCellTooltip"
|
||||
>{{ tableCellTooltip.text }}</div>
|
||||
|
||||
<el-dialog
|
||||
:visible.sync="dialogVisible"
|
||||
:title="isEdit ? '编辑设计任务' : '新建设计任务'"
|
||||
@@ -426,10 +433,12 @@
|
||||
|
||||
<script>
|
||||
import TaskAttachments from '../components/TaskAttachments'
|
||||
import threeLineTableTooltip from '../mixins/threeLineTableTooltip'
|
||||
|
||||
export default {
|
||||
name: 'DesignReportTask',
|
||||
components: { TaskAttachments },
|
||||
mixins: [threeLineTableTooltip],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
@@ -542,7 +551,10 @@ export default {
|
||||
['预计开始时间_End', this.searchForm.planStartTo || ''],
|
||||
['预计结束时间_Start', this.searchForm.planEndFrom || ''],
|
||||
['预计结束时间_End', this.searchForm.planEndTo || ''],
|
||||
['单据状态', this.searchForm.status || '']
|
||||
['单据状态', this.searchForm.status || ''],
|
||||
['当前操作人ID', this.currentUserId()],
|
||||
['当前操作人', this.currentUserName()],
|
||||
['角色编号', this.currentRoleId()]
|
||||
]
|
||||
},
|
||||
async searchTable() {
|
||||
@@ -777,7 +789,10 @@ export default {
|
||||
['预计开始时间_End', ''],
|
||||
['预计结束时间_Start', ''],
|
||||
['预计结束时间_End', ''],
|
||||
['单据状态', '']
|
||||
['单据状态', ''],
|
||||
['当前操作人ID', this.currentUserId()],
|
||||
['当前操作人', this.currentUserName()],
|
||||
['角色编号', this.currentRoleId()]
|
||||
]
|
||||
const data = this.CreateData('11', '设计报工_任务_查询', params)
|
||||
try {
|
||||
@@ -1003,13 +1018,15 @@ export default {
|
||||
}
|
||||
|
||||
.design-action-buttons {
|
||||
display: inline-flex;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
grid-auto-rows: 32px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: nowrap;
|
||||
gap: 10px;
|
||||
gap: 8px 10px;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
height: 72px;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.design-action-buttons ::v-deep .el-button {
|
||||
@@ -1023,6 +1040,14 @@ export default {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.design-action-more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.danger-action {
|
||||
color: #f56c6c;
|
||||
}
|
||||
@@ -1035,7 +1060,8 @@ export default {
|
||||
|
||||
.design-data-table ::v-deep .el-table__row,
|
||||
.design-data-table ::v-deep .el-table__body td {
|
||||
height: 108px;
|
||||
height: 108px !important;
|
||||
max-height: 108px;
|
||||
}
|
||||
|
||||
.design-data-table ::v-deep .el-table__body td {
|
||||
@@ -1047,11 +1073,15 @@ export default {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.design-data-table ::v-deep .el-table__body .cell,
|
||||
.design-data-table ::v-deep .el-table__body .cell.el-tooltip {
|
||||
.design-data-table ::v-deep .el-table__body .three-line-table-cell .cell {
|
||||
display: -webkit-box !important;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
white-space: normal !important;
|
||||
overflow: visible;
|
||||
text-overflow: clip;
|
||||
height: 72px;
|
||||
max-height: 72px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
}
|
||||
@@ -1063,20 +1093,45 @@ export default {
|
||||
}
|
||||
|
||||
.note-history {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
width: 100%;
|
||||
height: 72px;
|
||||
min-height: 72px;
|
||||
max-height: 72px;
|
||||
line-height: 24px;
|
||||
white-space: pre-line;
|
||||
overflow: visible;
|
||||
white-space: pre-wrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.note-tooltip-content {
|
||||
max-width: 520px;
|
||||
.table-cell-full-tooltip {
|
||||
position: fixed;
|
||||
z-index: 4000;
|
||||
width: max-content;
|
||||
max-width: 600px;
|
||||
min-width: 80px;
|
||||
max-height: 60vh;
|
||||
padding: 10px 12px;
|
||||
color: #fff;
|
||||
background: #303133;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.18);
|
||||
pointer-events: auto;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
white-space: pre-line;
|
||||
white-space: pre-wrap;
|
||||
overflow-y: auto;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
@media (max-width: 624px) {
|
||||
.table-cell-full-tooltip {
|
||||
max-width: calc(100vw - 24px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tableCellTooltip: {
|
||||
visible: false,
|
||||
text: '',
|
||||
left: 0,
|
||||
top: 0,
|
||||
placement: 'top'
|
||||
},
|
||||
tableCellTooltipRequestId: 0,
|
||||
tableCellTooltipHideTimer: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
tableCellTooltipStyle() {
|
||||
const isBottom = this.tableCellTooltip.placement === 'bottom'
|
||||
return {
|
||||
left: `${this.tableCellTooltip.left}px`,
|
||||
top: `${this.tableCellTooltip.top}px`,
|
||||
transform: isBottom ? 'translate(-50%, 0)' : 'translate(-50%, -100%)'
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.clearThreeLineCellTooltipHideTimer()
|
||||
},
|
||||
methods: {
|
||||
getThreeLineCellClassName({ column }) {
|
||||
return column && column.label === '操作' ? 'operation-table-cell' : 'three-line-table-cell'
|
||||
},
|
||||
showThreeLineCellTooltip(row, column, cell) {
|
||||
this.hideThreeLineCellTooltip()
|
||||
if (!cell || !column || column.label === '操作') return
|
||||
|
||||
const requestId = ++this.tableCellTooltipRequestId
|
||||
this.$nextTick(() => {
|
||||
if (requestId !== this.tableCellTooltipRequestId) return
|
||||
const content = cell.querySelector('.note-history') || cell.querySelector('.cell')
|
||||
if (!content) return
|
||||
|
||||
const text = String(content.innerText || content.textContent || '').trim()
|
||||
const isOverflowing = content.scrollHeight > content.clientHeight + 1
|
||||
if (!text || !isOverflowing) return
|
||||
|
||||
const rect = content.getBoundingClientRect()
|
||||
const viewportWidth = window.innerWidth || document.documentElement.clientWidth
|
||||
const tooltipWidth = Math.min(600, viewportWidth - 24)
|
||||
const halfWidth = tooltipWidth / 2
|
||||
const left = Math.min(viewportWidth - 12 - halfWidth, Math.max(12 + halfWidth, rect.left + rect.width / 2))
|
||||
const placement = rect.top >= 160 ? 'top' : 'bottom'
|
||||
|
||||
this.tableCellTooltip = {
|
||||
visible: true,
|
||||
text,
|
||||
left,
|
||||
top: placement === 'top' ? rect.top - 8 : rect.bottom + 8,
|
||||
placement
|
||||
}
|
||||
})
|
||||
},
|
||||
scheduleHideThreeLineCellTooltip() {
|
||||
this.clearThreeLineCellTooltipHideTimer()
|
||||
this.tableCellTooltipHideTimer = window.setTimeout(() => {
|
||||
this.hideThreeLineCellTooltip()
|
||||
}, 150)
|
||||
},
|
||||
keepThreeLineCellTooltipOpen() {
|
||||
this.clearThreeLineCellTooltipHideTimer()
|
||||
},
|
||||
clearThreeLineCellTooltipHideTimer() {
|
||||
if (!this.tableCellTooltipHideTimer) return
|
||||
window.clearTimeout(this.tableCellTooltipHideTimer)
|
||||
this.tableCellTooltipHideTimer = null
|
||||
},
|
||||
hideThreeLineCellTooltip() {
|
||||
this.clearThreeLineCellTooltipHideTimer()
|
||||
this.tableCellTooltipRequestId++
|
||||
this.tableCellTooltip.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user