feat: 完善设计任务与工时维护

This commit is contained in:
2026-07-17 18:27:47 +08:00
parent 5b7397237e
commit e31027aa9d
7 changed files with 1228 additions and 108 deletions

View File

@@ -0,0 +1,409 @@
USE [YL_MESDB];
GO
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
IF COL_LENGTH(N'[dbo].[MES_设计报工_任务]', N'任务来源') IS NULL
BEGIN
ALTER TABLE [dbo].[MES_设计报工_任务] ADD [] nvarchar(200) NULL;
END
GO
DECLARE @ sysname;
DECLARE @SQL nvarchar(max);
SELECT TOP (1) @ = cc.[name]
FROM sys.check_constraints AS cc
WHERE cc.[parent_object_id] = OBJECT_ID(N'[dbo].[MES_设计报工_任务说明]')
AND cc.[definition] LIKE N'%说明类型%';
IF @ IS NOT NULL
BEGIN
SET @SQL = N'ALTER TABLE [dbo].[MES_设计报工_任务说明] DROP CONSTRAINT '
+ QUOTENAME(@) + N';';
EXEC sys.sp_executesql @SQL;
END
GO
ALTER TABLE [dbo].[MES_设计报工_任务说明] WITH CHECK
ADD CONSTRAINT [CK_MES_设计报工_任务说明_类型]
CHECK ([] IN (N'领导批示', N'异常说明', N'奇思妙想'));
GO
CREATE OR ALTER PROCEDURE [dbo].[_领导批示权限_查询]
@ nvarchar(100) = N''
AS
BEGIN
SET NOCOUNT ON;
SELECT CAST(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 AS int) AS [];
END
GO
CREATE OR ALTER PROCEDURE [dbo].[_任务说明_新增]
@DID int,
@ nvarchar(20),
@ nvarchar(2000),
@ID nvarchar(100) = N'',
@ nvarchar(100) = N'',
@ nvarchar(100) = N''
AS
BEGIN
SET NOCOUNT ON;
SET @ = LTRIM(RTRIM(ISNULL(@, N'')));
SET @ = LTRIM(RTRIM(ISNULL(@, N'')));
IF @ NOT IN (N'领导批示', N'异常说明', N'奇思妙想')
BEGIN
SELECT CAST(0 AS int) AS [result], N'说明类型不正确' AS [message];
RETURN;
END
IF @ = N''
BEGIN
SELECT CAST(0 AS int) AS [result], N'说明内容不能为空' AS [message];
RETURN;
END
IF @ = N'领导批示'
AND NOT EXISTS
(
SELECT 1
FROM [dbo].[_角色信息]
WHERE CONVERT(nvarchar(100), [Roles_number]) = @
AND ([Roles_Function] LIKE N'%领导%' OR [Roles_Function] LIKE N'%管理员%')
)
BEGIN
SELECT CAST(0 AS int) AS [result], N'当前角色无领导批示权限' AS [message];
RETURN;
END
IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID)
BEGIN
SELECT CAST(0 AS int) AS [result], N'任务不存在' AS [message];
RETURN;
END
INSERT INTO [dbo].[MES_设计报工_任务说明]
([DID], [], [], [ID], [])
VALUES
(@DID, @, @, NULLIF(@ID, N''), NULLIF(@, N''));
SELECT CAST(1 AS int) AS [result], N'保存成功' AS [message], CONVERT(int, SCOPE_IDENTITY()) AS [SID];
END
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''
AS
BEGIN
SET NOCOUNT ON;
DECLARE @1 datetime = TRY_CONVERT(datetime, NULLIF(@_Start, N''));
DECLARE @2 datetime = TRY_CONVERT(datetime, NULLIF(@_End, N''));
DECLARE @1 datetime = TRY_CONVERT(datetime, NULLIF(@_Start, N''));
DECLARE @2 datetime = TRY_CONVERT(datetime, NULLIF(@_End, N''));
SELECT TOP 1000
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
(
(NULLIF(@ID, N'') IS NULL AND NULLIF(@, N'') IS NULL)
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
CREATE OR ALTER PROCEDURE [dbo].[_任务_新增]
@ nvarchar(100) = N'',
@ nvarchar(100) = N'',
@ nvarchar(200) = N'',
@ nvarchar(100) = N'',
@ nvarchar(100) = N'',
@ nvarchar(200) = N'',
@ nvarchar(500) = N'',
@ nvarchar(100) = N'',
@ nvarchar(200) = N'',
@ nvarchar(max) = N'',
@ nvarchar(100) = N'',
@ nvarchar(500) = N'',
@ID nvarchar(1000) = N'',
@ nvarchar(1000) = N'',
@ nvarchar(30) = N'',
@ nvarchar(30) = N'',
@ nvarchar(100) = N'',
@ nvarchar(500) = N'',
@ID nvarchar(1000) = N'',
@ nvarchar(1000) = N''
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [dbo].[MES_设计报工_任务]
(
[], [], [], [], [], [], [],
[], [], [],
[], [], [ID], [], [ID], [],
[], [], [],
[], [], [], []
)
VALUES
(
NULLIF(@, N''), NULLIF(@, N''), NULLIF(@, N''), NULLIF(@, N''),
NULLIF(@, N''), NULLIF(@, N''), NULLIF(@, N''),
NULLIF(@, N''), NULLIF(@, N''), NULLIF(@, N''),
NULLIF(@, N''), NULLIF(@, N''), NULLIF(@ID, N''), NULLIF(@, N''),
NULLIF(@ID, N''), NULLIF(@, N''),
TRY_CONVERT(datetime, NULLIF(@, N'')), TRY_CONVERT(datetime, NULLIF(@, N'')), N'待开始',
NULLIF(@, N''), NULLIF(@, N''), GETDATE(), NULLIF(@, N'')
);
SELECT CAST(1 AS int) AS [result], N'新增成功' AS [message], SCOPE_IDENTITY() AS [DID];
END
GO
CREATE OR ALTER PROCEDURE [dbo].[_任务_编辑]
@DID int,
@ nvarchar(100) = N'',
@ nvarchar(100) = N'',
@ nvarchar(200) = N'',
@ nvarchar(100) = N'',
@ nvarchar(100) = N'',
@ nvarchar(200) = N'',
@ nvarchar(500) = N'',
@ nvarchar(100) = N'',
@ nvarchar(200) = N'',
@ nvarchar(max) = N'',
@ nvarchar(100) = N'',
@ nvarchar(500) = N'',
@ID nvarchar(1000) = N'',
@ nvarchar(1000) = N'',
@ nvarchar(30) = N'',
@ nvarchar(30) = N'',
@ nvarchar(100) = N'',
@ nvarchar(500) = N'',
@ID nvarchar(1000) = N'',
@ nvarchar(1000) = N''
AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS (SELECT 1 FROM [dbo].[MES_设计报工_任务] WHERE [DID] = @DID)
BEGIN
SELECT CAST(0 AS int) AS [result], N'任务不存在' AS [message];
RETURN;
END
UPDATE [dbo].[MES_设计报工_任务]
SET
[] = NULLIF(@, N''),
[] = NULLIF(@, N''),
[] = NULLIF(@, N''),
[] = NULLIF(@, N''),
[] = NULLIF(@, N''),
[] = NULLIF(@, N''),
[] = CASE
WHEN NULLIF(@, N'') IS NOT NULL AND ISNULL([], N'') = @
THEN NULLIF(@, N'')
ELSE []
END,
[] = NULLIF(@, N''),
[] = NULLIF(@, N''),
[] = CASE
WHEN NULLIF(@, N'') IS NOT NULL AND ISNULL([], N'') = @
THEN NULLIF(@, N'')
ELSE []
END,
[] = NULLIF(@, N''),
[] = NULLIF(@, N''),
[ID] = NULLIF(@ID, N''),
[] = NULLIF(@, N''),
[ID] = NULLIF(@ID, N''),
[] = NULLIF(@, N''),
[] = TRY_CONVERT(datetime, NULLIF(@, N'')),
[] = TRY_CONVERT(datetime, NULLIF(@, N'')),
[] = NULLIF(@, N''),
[] = GETDATE(),
[] = NULLIF(@, N'')
WHERE [DID] = @DID;
SELECT CAST(1 AS int) AS [result], N'编辑成功' AS [message];
END
GO

View File

@@ -3436,6 +3436,42 @@ pm run build通过仅有既有警告。
- 数据库明文密码没有进入提交内容。 - 数据库明文密码没有进入提交内容。
- 本条上传过程日志将通过后续独立提交同步到远程,确保工作区最终无未提交修改。 - 本条上传过程日志将通过后续独立提交同步到远程,确保工作区最终无未提交修改。
### 验证结果
- 上传前本地与远程分叉为 `0 0`
- 全工作区和暂存区 `git diff --check` 通过。
- 暂存区凭据特征扫描无命中。
- 两个设计报工页面 ESLint 通过。
- 最终生产构建通过。
- 功能提交已成功推送至远程。
## 2026-07-16 发货状态列表增加订单及生产数量字段
### 用户提问
- 用户要求修改 `ProductionManagement/DeliveryNoticeList/index`,增加订单数量(取计划数量)、入库数量、完成数量和合格数量四个字段。
### 执行过程
1. 从当前工作目录及元利相关项目中搜索目标路径,定位实际文件为 `C:\WorkYuanLy\MES_Manage_View_V20\src\views\ProductionManagement\DeliveryNoticeList\index.vue`
2. 检查目标页面现有实现,确认列表通过存储过程 `装配中心任务看板_发货状态查询` 获取数据并直接赋值给 `tableData`,现有“数量”列使用 `交货数量 || 计划数量`,页面已有统一的 `formatQuantity` 数量格式化方法。
3. 搜索项目内相同字段的使用方式,确认中文字段可以直接通过 `scope.row` 访问;检查项目依赖和构建命令,确认项目为 Vue 2、Element UI 和 Webpack 5。
4. 读取仓库根目录 `AGENTS.md`,确认每次执行后必须将提问、结论和完整执行过程以中文追加到 `gptlog-process/gpdlog.md`
5. 修改目标列表:
- 将原“数量”列调整为“订单数量”,固定读取 `计划数量`
- 新增“入库数量”列,读取 `入库数量`
- 新增“完成数量”列,读取 `完成数量`
- 新增“合格数量”列,读取 `合格数量`
- 四列均复用 `formatQuantity`,统一处理空值、整数和小数显示。
6. 使用文本检索复核目标页面,确认四个列名和对应字段均已写入,原“交货数量或计划数量”的混合显示逻辑已移除。
7. 首次执行 `npm run build` 时,构建超过 180 秒工具超时;期间只输出 Baseline、Browserslist 数据过期提示,没有模板或代码错误,超时进程随后已终止。
8. 使用更长超时重新执行 `npm run build`Webpack 在约 40 秒内成功完成生产构建。
9. 构建仅保留项目原有的大体积字体、图片、第三方库、入口文件体积警告,以及 Baseline、Browserslist 数据过期提示;没有新增编译错误。
10. 按仓库要求在本日志末尾追加本次完整中文执行记录,未修改或覆盖已有历史日志。
### 修改文件
- `src/views/ProductionManagement/DeliveryNoticeList/index.vue`
- `gptlog-process/gpdlog.md`
### 结论
- 发货状态列表现在包含订单数量、入库数量、完成数量和合格数量四个独立字段。
- 订单数量严格读取后端返回的 `计划数量`,不再与 `交货数量` 混用。 - 订单数量严格读取后端返回的 `计划数量`,不再与 `交货数量` 混用。
- 查询请求和筛选条件保持不变,四个字段直接使用现有存储过程返回值。 - 查询请求和筛选条件保持不变,四个字段直接使用现有存储过程返回值。
@@ -3594,3 +3630,393 @@ pm run build通过仅有既有警告。
- 数据库明文密码未进入任何提交内容。 - 数据库明文密码未进入任何提交内容。
- 本条上传过程日志将通过后续独立提交同步到远程,完成后再次校验本地与远程一致性。 - 本条上传过程日志将通过后续独立提交同步到远程,完成后再次校验本地与远程一致性。
### 验证结果
- 上传前本地与远程分叉为 `0 0`
- 工作区和暂存区空白检查通过。
- 暂存区凭据特征扫描无命中。
- HoursReport 页面 ESLint 通过。
- 生产构建通过。
- 独立 LocalDB 和目标数据库查询验证通过。
- 功能提交已成功推送至远程。
## 2026-07-17 设计任务分类、领导批示及历史记录权限调整
### 用户提问
- 用户要求修改 `src/views/ProductionManagement/DesignReportTask/Task/index.vue`,将分类改为固定下拉选项:实验、研发、方案评审、售前、订单、确认、售后问题指导、售后物料准备、返修品处理、其他。
- 用户要求任务描述和设计要求只有创建人可以修改。
- 用户要求在设计任务界面和报工界面的操作位置增加作用相同的“领导批示”,并将“领导批示”字段放在两个列表的第一列。
- 用户要求领导批示、异常、奇思妙想、进度按“日期+编辑人,换行,内容”的方式显示,并按倒序排列,第一条为最新内容。
### 执行过程
1. 读取仓库根目录 `AGENTS.md`,确认必须把提问、结论和完整执行过程以中文追加到 `gptlog-process/gpdlog.md`
2. 检查设计报工模块的 `Task/index.vue``Report/index.vue``HoursReport/index.vue`、现有存储过程脚本和当前用户 Vuex 字段,确认设计任务页为任务维护界面,报工页为开始、结束、完成及异常/奇思妙想录入界面。
3. 检查现有数据库脚本 `update_design_report_task_notes_and_restart_20260715.sql`,确认异常说明和奇思妙想存储在 `MES_设计报工_任务说明`,进度说明存储在 `MES_设计报工_记录`;现有聚合缺少编辑人且按正序返回。
4. 检查当前工作区,确认用户已有 `DeliveryNoticeList/index.vue``gptlog-process/gpdlog.md` 修改;本次保留这些修改,没有覆盖或回退。
5. 修改设计任务页面:
- 查询条件“类别”和新建/编辑表单“类别”改为固定选项下拉框。
- 在列表第一列增加固定的“领导批示”列。
- 在操作区增加“领导批示”按钮和录入弹窗,通过统一过程 `设计报工_任务说明_新增` 保存。
- 根据当前登录人员姓名与任务创建人判断编辑权限;非创建人打开编辑弹窗时,任务描述和设计要求禁用。
- 调整领导批示、进度说明、异常说明、奇思妙想的单元格样式,保留日期/编辑人与内容之间的换行,最多显示约四行并可通过提示框查看完整历史。
6. 修改设计报工页面:
- 查询条件“类别”使用与任务页面相同的固定下拉选项。
- 在列表第一列增加固定的“领导批示”列。
- 在操作区增加“领导批示”按钮,复用异常说明和奇思妙想的同一录入弹窗及保存过程。
- 同步调整四类历史字段的换行显示样式。
7. 新增数据库迁移 `db_backups/add_design_report_leader_instruction_and_note_history_20260717.sql`
- 将任务说明类型约束扩展为领导批示、异常说明、奇思妙想。
- 扩展 `设计报工_任务说明_新增`,允许保存领导批示。
- 更新 `设计报工_任务_查询`,返回领导批示,并为四类历史内容拼接日期、编辑人、换行和内容。
- 所有历史聚合按业务时间降序、流水号降序排列,时间相同时仍保证后录入内容在前。
- 更新 `设计报工_任务_编辑`,只有最后编辑人与创建人一致时才更新任务描述和设计要求,防止绕过前端直接调用接口越权修改。
8. 执行两个 Vue 文件的 ESLint检查通过仅输出项目已有的 Baseline 和 Browserslist 数据过期提示。
9. 执行目标文件 `git diff --check`,检查通过;仅有仓库换行符转换提示,无空白错误。
10. 在本机 SQL Server 2019 LocalDB 创建一次性 `YL_MESDB` 最小测试库,包含任务、报工记录和任务说明三张测试表以及测试数据。
11. 首次执行迁移时发现动态删除检查约束直接拼接 `QUOTENAME` 的写法在 SQL Server 2019 报语法错误;将其改为先生成变量,再通过 `sys.sp_executesql` 执行。
12. 从干净测试库重新执行修正后的迁移,执行成功。
13. 隔离数据库行为验证:
- “领导批示”可以通过统一任务说明过程保存。
- 最新领导批示位于较早批示之前,且显示为日期和编辑人后换行显示内容。
- 最新进度位于较早进度之前,并包含报工编辑人。
- 异常说明和奇思妙想同样按最新内容在前返回。
- 非创建人调用任务编辑过程后,任务描述和设计要求保持原值。
- 创建人调用任务编辑过程后,两字段正常更新。
14. 验证结束后删除 LocalDB 测试数据库和两个临时验证脚本,确认没有测试资源残留。
15. 尝试使用当前 Windows 身份连接 `192.168.2.92 / YL_MESDB` 做发布前检查,远端登录超时;未猜测或使用未提供的数据库凭据,因此本次迁移脚本未发布到生产库。
16. 执行 `npm run build`Webpack 生产构建成功仅保留项目已有的大资源体积、Baseline 和 Browserslist 数据过期警告,没有编译错误,也没有产生受版本控制的 `dist` 变化。
17. 检查现有本地开发服务,`https://localhost:1997/` 返回 HTTP 200。
18. 按仓库要求追加本条完整中文执行日志,并再次复核工作区差异。
### 修改文件
- `src/views/ProductionManagement/DesignReportTask/Task/index.vue`
- `src/views/ProductionManagement/DesignReportTask/Report/index.vue`
- `db_backups/add_design_report_leader_instruction_and_note_history_20260717.sql`
- `gptlog-process/gpdlog.md`
### 结论
- 设计任务分类已经改为用户指定的十项固定下拉选项,报工页查询使用同一选项集。
- 设计任务和报工列表的第一列均为领导批示,两个页面都可以通过同一数据库过程录入。
- 领导批示、异常说明、奇思妙想和进度说明统一显示日期、编辑人及换行后的内容,最新记录排在第一条。
- 任务描述和设计要求已经同时受到前端禁用和数据库过程保护,只有创建人可以修改。
- 前端与数据库迁移均已实现并通过本地验证;迁移脚本因生产数据库当前身份登录超时尚未发布。
### 验证结果
- 两个目标 Vue 文件 ESLint 通过。
- 目标差异空白检查通过。
- SQL Server 2019 LocalDB 迁移执行通过。
- 领导批示保存、四类历史格式及倒序验证通过。
- 创建人和非创建人权限行为验证通过。
- `npm run build` 生产构建通过。
- `https://localhost:1997/` 返回 HTTP 200。
- LocalDB 测试数据库和临时文件已清理。
## 2026-07-17 发布设计任务领导批示迁移到生产数据库
### 用户提问
- 用户提供生产数据库 `192.168.2.92``sa` 账号凭据,用于发布上一项设计任务分类、领导批示、历史记录格式和创建人编辑权限相关数据库迁移。
### 执行过程
1. 使用用户提供的数据库账号连接 `192.168.2.92 / YL_MESDB`;密码仅通过当前 PowerShell 进程的 `SQLCMDPASSWORD` 环境变量传递,命令结束后立即删除该环境变量,未将密码写入项目文件或本日志。
2. 发布前只读检查目标数据库和对象,确认当前数据库为 `YL_MESDB`,登录账号正确,并确认以下对象均存在:
- `dbo.MES_设计报工_任务说明`
- `dbo.设计报工_任务说明_新增`
- `dbo.设计报工_任务_查询`
- `dbo.设计报工_任务_编辑`
3. 使用 `sqlcmd -b -C -l 30 -f 65001` 执行迁移脚本 `db_backups/add_design_report_leader_instruction_and_note_history_20260717.sql`;发布过程返回成功,数据库上下文为 `YL_MESDB`
4. 发布后检查任务说明类型约束:
- 约束名称为 `CK_MES_设计报工_任务说明_类型`
- 约束已启用且为可信状态。
- 定义中同时包含领导批示、异常说明和奇思妙想,检查通过。
5. 检查三个过程的修改时间,均为 `2026-07-17 11:50:08`,确认本次发布已更新目标对象。
6. 使用 SQL Server 首结果集元数据检查 `设计报工_任务_查询`,确认第一列为非空 `nvarchar(max)` 类型的“领导批示”。
7. 检查过程定义,确认领导批示保存逻辑、进度及任务说明按时间倒序聚合、缺少编辑人时的兜底显示均已发布。
8. 首次自动检查创建人权限时使用 SQL `LIKE` 匹配含方括号的字段名,方括号被 SQL 解释为模式字符而产生误报;改用 `CHARINDEX` 分别检查任务描述 CASE、设计要求 CASE 和创建人与最后编辑人比较条件,三项均通过,未重新执行迁移。
9. 从生产任务表选择最新 DID实际执行更新后的 `设计报工_任务_查询`;查询成功,确认新聚合语句可以在生产真实数据上正常运行。该验证为只读操作,未新增或修改业务数据。
10. 按仓库 `AGENTS.md` 要求追加本条完整中文执行过程日志,日志不记录明文密码。
### 修改文件
- `gptlog-process/gpdlog.md`
### 结论
- 设计任务领导批示、四类历史记录格式及倒序、创建人编辑权限迁移已成功发布到 `192.168.2.92 / YL_MESDB`
- “领导批示”已经成为任务查询结果的第一列,数据库保存过程允许领导批示类型。
- 任务描述和设计要求的数据库创建人权限保护已生效。
- 数据库密码未写入任何项目文件或执行日志。
### 验证结果
- 生产数据库连接和发布前对象检查通过。
- 数据库迁移脚本执行通过。
- 任务说明约束启用、可信且定义正确。
- 三个目标过程修改时间已更新。
- 查询首列“领导批示”元数据检查通过。
- 历史格式及倒序定义检查通过。
- 创建人权限定义检查通过。
- 生产库真实 DID 查询执行通过。
## 2026-07-17 调整设计任务分类、增加任务来源并恢复默认行高
### 用户提问
- 用户要求分类选项删除“确认”,增加“售中”和“售后信息确认”。
- 用户要求增加“任务来源”字段并放在类别旁边。
- 用户要求列表页面不要根据历史内容调整行高,使用默认行高。
### 执行过程
1. 检查设计任务页 `Task/index.vue`、设计报工页 `Report/index.vue`、上一轮数据库迁移和当前工作区状态。
2. 确认两个页面共用相同分类选项;任务表尚无“任务来源”字段;领导批示、进度说明、异常说明和奇思妙想的 `.note-history` 样式使用多行显示并设置了最小、最大高度。
3. 确认工作区还存在用户的发货列表、工时校验和工时编辑等修改,本次没有覆盖或回退这些无关内容。
4. 修改设计任务页分类选项,删除独立选项“确认”,新增“售中”和“售后信息确认”;最终选项为实验、研发、方案评审、售前、售中、订单、售后信息确认、售后问题指导、售后物料准备、返修品处理、其他。
5. 在设计任务页增加任务来源:
- 查询区在类别右侧增加任务来源文本筛选。
- 列表在类别右侧增加任务来源列。
- 新建、编辑表单在类别右侧增加任务来源输入框,最大长度 200。
- 空表单、查询参数、实时查询参数和新增/编辑保存参数均接入任务来源。
6. 在设计报工页同步使用新分类选项,并在类别右侧增加任务来源查询条件和列表列;普通查询、最新任务查询及当前未结束任务查询均传递任务来源参数。
7. 将两个页面的历史内容单元格恢复为单行、20 像素最小高度和超出省略显示,移除多行及最大高度设置;完整历史仍可通过原有悬浮提示查看,因此表格行高不再随内容增加。
8. 扩展数据库迁移 `db_backups/add_design_report_leader_instruction_and_note_history_20260717.sql`
- 当字段不存在时,为 `MES_设计报工_任务` 增加可空 `nvarchar(200)` 任务来源列。
- 更新 `设计报工_任务_查询`,增加任务来源参数、返回列和模糊筛选,并把返回列放在类别与任务描述之间。
- 更新 `设计报工_任务_新增`,保存任务来源。
- 更新 `设计报工_任务_编辑`,更新任务来源,同时保留上一轮任务描述和设计要求的创建人权限保护。
9. 执行两个 Vue 文件 ESLint 和目标差异空白检查,均通过;仅输出项目已有的 Baseline、Browserslist 数据过期及换行符提示。
10. 在 SQL Server 2019 LocalDB 创建一次性最小测试库和三张设计报工测试表,执行扩展后的迁移成功。
11. 首次运行隔离验证命令时漏传 LocalDB 数据库名,连接默认落到 `master`,因此提示找不到测试过程和表;该命令未修改任何业务数据。补充 `-d YL_MESDB` 后重新验证成功。
12. LocalDB 验证结果:
- 任务来源字段为 `nvarchar(200)`
- 查询结果中的类别、任务来源、任务描述依次为第 7、8、9 列。
- 查询、新增、编辑三个过程均包含任务来源参数。
- 使用“售中”和“客户现场”新增测试任务成功。
- 将分类编辑为“售后信息确认”、任务来源编辑为“售后反馈”成功。
- 按“售后反馈”筛选查询成功返回测试任务。
13. 删除 LocalDB 测试数据库和临时验证脚本,确认没有临时资源残留。
14. 使用用户已提供的生产数据库账号连接 `192.168.2.92 / YL_MESDB`,发布前确认生产任务表尚无任务来源字段和相应过程参数。
15. 通过当前进程的 `SQLCMDPASSWORD` 环境变量执行扩展后的迁移,发布成功;密码未写入脚本或日志,命令结束后删除环境变量。
16. 生产库发布后验证:
- 任务来源字段存在且为 `nvarchar(200)`
- 查询结果中任务来源位于类别和任务描述之间。
- 查询、新增、编辑三个过程均包含任务来源参数。
- 三个过程修改时间均为 `2026-07-17 13:36:33`
- 使用生产库最新真实 DID 执行带任务来源参数的查询成功,验证过程为只读操作。
17. 执行 `npm run build`Webpack 生产构建成功;仅有项目已有的大资源体积和浏览器数据过期警告,没有编译错误或受版本控制的构建产物变化。
18. 检查 `https://localhost:1997/` 返回 HTTP 200检查分类、任务来源参数、单行样式和临时资源均符合要求检查数据库密码未进入仓库。
19.`AGENTS.md` 要求追加本条完整中文执行日志。
### 修改文件
- `src/views/ProductionManagement/DesignReportTask/Task/index.vue`
- `src/views/ProductionManagement/DesignReportTask/Report/index.vue`
- `db_backups/add_design_report_leader_instruction_and_note_history_20260717.sql`
- `gptlog-process/gpdlog.md`
### 结论
- 分类已删除“确认”,增加“售中”和“售后信息确认”,两个页面选项一致。
- 任务来源已经加入设计任务的查询、新建、编辑和列表,并加入设计报工的查询和列表,显示位置紧邻类别。
- 列表历史内容恢复单行省略显示,行高不再根据内容自动增加,悬浮提示仍显示完整内容。
- 任务来源数据库字段和查询、新增、编辑过程已发布到生产数据库。
### 验证结果
- 两个目标 Vue 文件 ESLint 通过。
- 目标差异空白检查通过。
- LocalDB 任务来源新增、编辑、筛选和列顺序验证通过。
- 临时测试数据库和脚本已清理。
- 生产数据库迁移发布成功。
- 生产库字段、三个过程参数和查询列顺序检查通过。
- 生产库真实 DID 查询通过。
- `npm run build` 生产构建通过。
- `https://localhost:1997/` 返回 HTTP 200。
## 2026-07-17 迁移设计任务完成功能并增加领导批示角色权限
### 用户提问
- 用户要求把“完成”功能由设计报工页面迁移到设计任务页面。
- 用户要求设计任务和设计报工页面默认不显示已完成任务。
- 用户要求领导批示按钮增加权限限制,只有权限包含“领导”的角色才能显示。
- 用户随后补充:权限包含“管理员”的角色也可以显示领导批示按钮。
### 执行过程
1. 检查设计任务页、设计报工页、用户登录、Vuex 用户状态、动态路由权限、数据库角色表和设计报工相关过程。
2. 确认原“完成”按钮和完整校验逻辑位于 `Report/index.vue`,包括实时任务查询、未结束报工校验、至少一次已结束报工校验、完成确认和 `设计报工_任务_完成` 调用。
3. 确认当前登录状态只保存角色编号Vuex 的 `roles` 固定为 `admin` 以驱动历史路由框架,不能代表真实角色功能;真实角色名称存储在 `登录基础数据_角色信息.Roles_Function`
4. 只读检查生产角色表,确认存在角色功能包含“领导”的角色,例如质量部领导和采购部领导;数据库角色表及字段可用于精确权限判断。
5. 修改设计任务页:
- 在状态选项中增加“未完成”,并把默认状态设为“未完成”。
- 在操作区增加“完成”按钮。
- 迁入原报工页的完整完成逻辑:实时刷新任务、检查未结束人员、检查是否已有报工、二次确认、调用 `设计报工_任务_完成` 并刷新列表。
- 增加独立动作加载状态,防止完成操作重复提交。
- 将原仅用于删除的实时任务查询提示调整为完成和删除均适用的通用提示。
6. 修改设计报工页:
- 删除“完成”按钮、`canComplete``completeTask` 方法。
- 缩小操作列宽度。
- 状态选项增加“未完成”,默认状态设为“未完成”。
7. 两个页面都会在首次加载时使用当前角色编号调用 `设计报工_领导批示权限_查询`;按钮默认隐藏,只有查询返回有权限时才显示。
8. 根据用户补充要求,将权限条件定义为当前角色功能包含“领导”或“管理员”任一文本;前端变量统一命名为 `canUseLeaderInstruction`,避免仍表达为仅领导角色。
9. 两个页面保存领导批示时都额外传递当前角色编号;异常说明和奇思妙想继续使用同一过程,不受领导批示角色限制。
10. 扩展数据库迁移脚本:
- 新增 `设计报工_领导批示权限_查询`,按角色编号检查角色功能是否包含“领导”或“管理员”。
- `设计报工_任务说明_新增` 增加角色编号参数;当说明类型为领导批示时,在数据库再次校验领导或管理员权限,无权限返回“当前角色无领导批示权限”。
- `设计报工_任务_查询` 增加“未完成”状态语义,过滤所有单据状态为“已完成”的任务;全部和其他具体状态查询保持原有行为。
11. 执行两个 Vue 文件 ESLint 和目标差异空白检查,均通过;只有项目已有的浏览器数据过期及换行符提示。
12. 在 SQL Server 2019 LocalDB 创建一次性最小测试库,构造领导角色、管理员角色、普通角色、未完成任务和已完成任务,执行迁移成功。
13. LocalDB 权限验证:
- 领导角色权限结果为 1。
- 管理员角色权限结果为 1。
- 普通角色权限结果为 0。
- 普通角色保存领导批示被数据库拒绝,且任务说明表中没有越权记录。
- 领导角色和管理员角色分别保存领导批示成功。
- 普通角色保存异常说明成功,确认权限没有错误限制其他说明类型。
14. LocalDB 默认筛选验证:任务表包含一条待开始、一条已完成任务,使用“未完成”查询只返回待开始任务,返回数量为 1已完成数量为 0。
15. 删除 LocalDB 测试数据库和临时验证脚本,确认无测试资源残留。
16. 使用用户已提供的生产数据库账号执行扩展后的迁移;密码只通过当前命令进程环境变量传递,命令结束后清理,未写入仓库或日志。
17. 生产库验证结果:
- 随机选择实际领导、管理员和普通角色调用权限过程,结果依次为 1、1、0。
- 权限查询过程、任务说明新增过程和任务查询过程修改时间均为 `2026-07-17 14:14:39`
- 任务说明新增过程确认包含角色编号参数。
- `设计报工_任务_完成` 过程仍存在,完成按钮迁移没有改变其数据库业务逻辑。
- 使用真实生产数据执行“未完成”查询返回 7 条,已完成数量为 0查询过程仅执行只读验证。
18. 执行代码检索,确认完成按钮和相关方法只存在于设计任务页,设计报工页不再包含完成入口;两个页面均默认选择“未完成”,领导批示按钮均使用权限变量控制。
19. 执行 `npm run build`,生产构建成功;仅有项目已有的大资源体积和浏览器数据过期警告,没有编译错误或受版本控制的构建产物变化。
20. 检查 `https://localhost:1997/` 返回 HTTP 200检查数据库密码未进入仓库`AGENTS.md` 要求追加本条完整中文日志。
### 修改文件
- `src/views/ProductionManagement/DesignReportTask/Task/index.vue`
- `src/views/ProductionManagement/DesignReportTask/Report/index.vue`
- `db_backups/add_design_report_leader_instruction_and_note_history_20260717.sql`
- `gptlog-process/gpdlog.md`
### 结论
- “完成”按钮及全部校验逻辑已经从设计报工页迁移到设计任务页。
- 设计任务和设计报工页面默认只显示未完成任务,用户仍可通过状态下拉查看全部或指定状态。
- 领导批示按钮只有当前角色功能包含“领导”或“管理员”时显示。
- 领导批示保存过程具备相同的数据库权限校验,普通角色不能绕过页面直接提交。
- 权限过程和未完成筛选已发布生产数据库。
### 验证结果
- 两个目标 Vue 文件 ESLint 通过。
- 目标差异空白检查通过。
- LocalDB 领导、管理员、普通角色权限验证通过。
- LocalDB 领导批示写入和越权拦截验证通过。
- LocalDB 未完成默认筛选验证通过。
- 临时测试资源已清理。
- 生产数据库迁移发布成功。
- 生产库实际角色权限结果为领导 1、管理员 1、普通角色 0。
- 生产库未完成查询返回 7 条,已完成数量为 0。
- `npm run build` 生产构建通过。
- `https://localhost:1997/` 返回 HTTP 200。
## 2026-07-17 清空生产数据库全部设计报工业务数据
### 用户提问
- 用户要求清空所有设计数据。
### 执行过程
1. 将本次清理范围限定为设计报工模块的业务数据表,不删除表结构、存储过程、菜单和项目、物料、人员等基础资料。
2. 使用用户已提供的生产数据库账号连接 `192.168.2.92 / YL_MESDB`;密码仅通过当前命令进程环境变量传递,命令结束后立即清理,未写入仓库或日志。
3. 发布前查询所有名称包含“设计报工”的生产业务表及行数,确认存在四张表:
- `MES_设计报工_任务`11 条。
- `MES_设计报工_记录`40 条。
- `MES_设计报工_任务说明`10 条。
- `MES_设计报工_校验记录`16 条。
4. 检查外键关系,确认报工记录引用任务且删除规则为 `NO_ACTION`,任务说明引用任务且删除规则为 `CASCADE`;校验记录包含 RID 和 DID 引用字段但没有数据库外键。
5. 检查四张表的自增列,分别为任务 DID、报工记录 RID、任务说明 SID、校验记录 VID。
6. 在单个数据库事务中按依赖顺序执行清理:校验记录、任务说明、报工记录、任务。
7. 删除后在提交前再次检查四张表;如果任一表仍有数据则抛出错误并回滚整个事务。本次检查全部为空,事务成功提交。
8. 在同一事务中将四张表的自增值重置为 0使后续新增的第一条数据从 1 开始。
9. 数据库返回的实际删除数量为:任务 11、报工记录 40、任务说明 10、校验记录 16总计 77 条。
10. 提交后再次查询四张表,行数均为 0再次查询四个自增列当前值均为 0。
11. 按仓库 `AGENTS.md` 要求在日志末尾追加本条完整中文执行记录。
### 修改文件
- `gptlog-process/gpdlog.md`
### 结论
- 生产数据库中设计报工模块的任务、报工记录、任务说明和校验记录已全部清空。
- 共删除 77 条业务数据,四张表当前均为 0 行。
- 四张表自增值已重置,后续新数据编号从 1 开始。
- 表结构、存储过程、菜单和基础资料保持不变。
### 验证结果
- 事务删除成功,无回滚或外键错误。
- 任务表0 条,自增值 0。
- 报工记录表0 条,自增值 0。
- 任务说明表0 条,自增值 0。
- 校验记录表0 条,自增值 0。
## 2026-07-17 放大设计列表行高字体并统一报工字段顺序
### 用户提问
- 用户先反馈分类删除“确认”、增加“售中”和“售后信息确认”后,设计任务界面似乎仍有“确认”。
- 用户随后要求修改设计任务和设计报工页面:列表行高变成三倍、修改字体大小、相应调整列宽,并让设计报工列表字段位置与设计任务一致。
### 执行过程
1. 检查当前设计任务和设计报工列表模板、样式、分类选项和工作区状态。
2. 确认两个页面的分类数组均为实验、研发、方案评审、售前、售中、订单、售后信息确认、售后问题指导、售后物料准备、返修品处理、其他;源码中不存在独立的“确认”选项,“确认”文本只作为“售后信息确认”的组成部分存在。
3. 检查当前设计任务列表字段顺序确认在本次修改前已经调整为领导批示、DID、状态、任务描述、设计要求、指派对象、预计开始、预计结束、进度说明、异常说明、奇思妙想、项目号、物料编码、物料名称、图号、类别、任务来源、父件物料编码、研发立项号、研发目的、对其可见、报工次数、未结束、设计正在对应、创建日期、创建人、备注、操作。
4. 以当前设计任务列表为唯一顺序基准,重排设计报工列表全部共同字段,避免按旧版顺序推断。
5. 在设计报工列表补齐原来未显示的共同字段:父件物料编码、研发立项号、研发目的、对其可见、创建日期、创建人和备注。
6. 自动提取两个 Vue 模板中的列名进行顺序比对,确认两个页面的 27 个共同字段完全同序;设计报工特有的“最后开始”和“最后结束”放在共同字段之后、操作列之前。
7. 为两个列表统一增加 `design-data-table` 样式类,并固定数据行和单元格高度为 108 像素,约为原 mini 表格行高的三倍。
8. 统一字体和垂直尺寸:
- 表格正文调整为 16 像素。
- 表头调整为 15 像素、高度 48 像素。
- 操作按钮调整为 15 像素。
- 状态标签调整为 14 像素、高度 30 像素。
- 单元格统一使用 24 像素行高。
9. 历史内容单元格在固定行高中使用 72 像素内容区、24 像素行高,最多展示三行并保留原有悬浮完整内容,防止内容继续撑高表格行。
10. 同步加宽两个页面的对应列:领导批示和三类历史列 360任务描述和设计要求 320人员及可见字段 200 至 220日期字段 180物料及研发字段按内容调整为 150 至 280。
11. 设计任务操作列调整为 340 像素,设计报工操作列调整为 440 像素,保证放大后的按钮和权限动态显示不会挤压换行。
12. 首次 ESLint 和差异空白检查发现设计任务模板有两处空白行带尾随空格;清理后重新执行,两项检查均通过。
13. 执行两个目标 Vue 文件 ESLint检查通过仅输出项目已有的 Baseline 和 Browserslist 数据过期提示。
14. 执行 `npm run build`Webpack 生产构建成功仅有项目已有的大资源体积和浏览器数据过期警告没有模板、JavaScript 或样式错误,也没有产生受版本控制的构建产物变化。
15. 检查 `https://localhost:1997/` 返回 HTTP 200再次核对分类源码没有独立“确认”并确认工作区其他已有修改未被覆盖或回退。
16. 本次仅修改前端列表布局和样式,不修改或写入生产数据库业务数据。
17. 按仓库 `AGENTS.md` 要求在日志末尾追加本条完整中文执行记录。
### 修改文件
- `src/views/ProductionManagement/DesignReportTask/Task/index.vue`
- `src/views/ProductionManagement/DesignReportTask/Report/index.vue`
- `gptlog-process/gpdlog.md`
### 结论
- 设计任务和设计报工列表数据行已统一固定为 108 像素,字体、表头、标签和操作按钮同步放大。
- 两个页面的对应列宽已经统一加宽,三行历史内容不会继续撑高列表。
- 设计报工的 27 个共同字段已经与当前设计任务列表完全同序,并补齐缺少的字段。
- 设计报工特有的最后开始和最后结束保留在共同字段之后。
- 两个分类数组均无独立“确认”选项,保留的是“售后信息确认”。
### 验证结果
- 两个列表共同字段顺序自动比对通过。
- 分类独立“确认”文本检查无命中。
- 两个目标 Vue 文件 ESLint 通过。
- 目标文件差异空白检查通过。
- `npm run build` 生产构建通过。
- `https://localhost:1997/` 返回 HTTP 200。
## 2026-07-17 设计任务和设计报工列表长文本自动换行
### 用户提问
- 用户要求列表内容超出列宽时不要省略,改为换行显示。
### 执行过程
1. 检查上一轮设计任务和设计报工列表样式,确认列表基础行高为 108 像素,普通字段仍带 Element UI 的 `show-overflow-tooltip` 省略行为,历史内容限制在 72 像素三行并隐藏超出内容。
2. 保留上一轮统一后的列宽、字体大小和字段顺序,不修改数据库、业务逻辑或查询参数。
3. 在两个页面的 `design-data-table` 表格正文中统一覆盖普通单元格和 Element UI tooltip 单元格样式:
- `white-space: normal !important`,允许按列宽自动换行。
- `text-overflow: clip`,取消省略号。
- `overflow: visible`,不裁剪超出内容。
- `overflow-wrap: anywhere``word-break: break-word`,长编号、无空格文本也可以换行。
4. 修改两个页面的历史内容样式,移除 72 像素最大高度和隐藏裁剪;保留 72 像素最小高度及原始换行格式,内容超过三行时完整展开。
5. 保留数据单元格的 108 像素基础高度;当换行内容需要更多空间时,由表格自动增加该行高度,避免文字覆盖相邻行。
6. 执行两个目标 Vue 文件 ESLint检查通过仅输出项目已有的 Baseline 和 Browserslist 数据过期提示。
7. 执行目标文件差异空白检查,检查通过;只有仓库换行符转换提示。
8. 通过文本检查确认两个页面均包含自动换行、取消省略和长单词断行样式,同时不存在历史内容 `max-height: 72px``text-overflow: ellipsis` 残留。
9. 执行 `npm run build`Webpack 生产构建成功;仅有项目已有的大资源体积和浏览器数据过期警告,没有模板或样式编译错误,也没有产生受版本控制的构建产物变化。
10. 检查 `https://localhost:1997/` 返回 HTTP 200。
11. 按仓库 `AGENTS.md` 要求在日志末尾追加本条完整中文执行记录。
### 修改文件
- `src/views/ProductionManagement/DesignReportTask/Task/index.vue`
- `src/views/ProductionManagement/DesignReportTask/Report/index.vue`
- `gptlog-process/gpdlog.md`
### 结论
- 设计任务和设计报工列表中的普通字段、编号和历史内容均按列宽自动换行。
- 列表不再使用省略号,也不再裁剪超过三行的历史内容。
- 108 像素作为基础行高保留,内容较多时表格行会继续增长并完整显示。

View File

@@ -90,8 +90,17 @@
<el-table-column align="center" label="销售订单" prop="合同号" width="110" /> <el-table-column align="center" label="销售订单" prop="合同号" width="110" />
<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="80"> <el-table-column align="center" label="订单数量" width="90">
<template slot-scope="scope">{{ formatQuantity(scope.row.交货数量 || scope.row.计划数量) }}</template> <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="90">
<template slot-scope="scope">{{ formatQuantity(scope.row.合格数量) }}</template>
</el-table-column> </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>

View File

@@ -60,10 +60,15 @@
/> />
</el-select> </el-select>
<span class="show-text">类别:</span> <span class="show-text">类别:</span>
<el-input v-model="searchForm.category" clearable size="small" style="width: 120px; margin-right: 8px" /> <el-select v-model="searchForm.category" clearable size="small" style="width: 150px; margin-right: 8px">
<el-option v-for="item in categoryOptions" :key="item" :label="item" :value="item" />
</el-select>
<span class="show-text">任务来源:</span>
<el-input v-model="searchForm.taskSource" clearable size="small" style="width: 140px; margin-right: 8px" />
<span class="show-text">状态:</span> <span class="show-text">状态:</span>
<el-select v-model="searchForm.status" clearable size="small" style="width: 110px; margin-right: 8px"> <el-select v-model="searchForm.status" clearable size="small" style="width: 110px; margin-right: 8px">
<el-option label="全部" value="全部" /> <el-option label="全部" value="全部" />
<el-option label="未完成" value="未完成" />
<el-option label="待开始" value="待开始" /> <el-option label="待开始" value="待开始" />
<el-option label="执行中" value="执行中" /> <el-option label="执行中" value="执行中" />
<el-option label="已结束" value="已结束" /> <el-option label="已结束" value="已结束" />
@@ -74,6 +79,7 @@
<el-table <el-table
v-loading="loading" v-loading="loading"
class="design-data-table"
:data="tableData" :data="tableData"
border border
height="74vh" height="74vh"
@@ -81,25 +87,26 @@
size="mini" size="mini"
style="width: 100%; margin-top: 12px" style="width: 100%; margin-top: 12px"
> >
<el-table-column align="center" fixed label="DID" prop="DID" width="70" /> <el-table-column align="left" fixed label="领导批示" prop="领导批示" width="360">
<el-table-column align="center" fixed label="状态" prop="单据状态" width="90"> <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" />
<el-table-column align="center" fixed label="状态" prop="单据状态" width="110">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag :type="getStatusType(scope.row.单据状态)" size="mini">{{ scope.row.单据状态 }}</el-tag> <el-tag :type="getStatusType(scope.row.单据状态)" size="mini">{{ scope.row.单据状态 }}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="left" label="项目号" prop="项目号" width="120" show-overflow-tooltip /> <el-table-column align="left" label="任务描述" prop="任务描述" width="320" show-overflow-tooltip />
<el-table-column align="left" label="物料编码" prop="物料编码" width="170" show-overflow-tooltip /> <el-table-column align="left" label="设计要求" prop="设计要求" width="320" show-overflow-tooltip />
<el-table-column align="left" label="物料名称" prop="物料名称" width="180" show-overflow-tooltip /> <el-table-column align="left" label="指派对象" prop="指派对象" width="220" show-overflow-tooltip />
<el-table-column align="left" label="图号" prop="图号" width="120" show-overflow-tooltip /> <el-table-column align="center" label="预计开始" prop="预计开始时间" width="180" />
<el-table-column align="left" label="类别" prop="类别" width="120" show-overflow-tooltip /> <el-table-column align="center" label="预计结束" prop="预计结束时间" width="180" />
<el-table-column align="left" label="任务描述" prop="任务描述" width="220" show-overflow-tooltip /> <el-table-column align="left" label="进度说明" prop="进度说明" width="360">
<el-table-column align="left" label="指派对象" prop="指派对象" width="180" show-overflow-tooltip />
<el-table-column align="center" label="预计开始" prop="预计开始时间" width="150" />
<el-table-column align="center" label="预计结束" prop="预计结束时间" width="150" />
<el-table-column align="center" label="报工次数" prop="报工次数" width="90" />
<el-table-column align="center" label="未结束" prop="未结束报工数" width="80" />
<el-table-column align="left" label="设计正在对应" prop="未结束报工人员" width="150" show-overflow-tooltip />
<el-table-column align="left" label="进度说明" prop="进度说明" width="240">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tooltip :disabled="!scope.row.进度说明" effect="dark" placement="top" :open-delay="300"> <el-tooltip :disabled="!scope.row.进度说明" effect="dark" placement="top" :open-delay="300">
<div slot="content" class="note-tooltip-content">{{ scope.row.进度说明 }}</div> <div slot="content" class="note-tooltip-content">{{ scope.row.进度说明 }}</div>
@@ -107,7 +114,7 @@
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="left" label="异常说明" prop="异常说明" width="240"> <el-table-column align="left" label="异常说明" prop="异常说明" width="360">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tooltip :disabled="!scope.row.异常说明" effect="dark" placement="top" :open-delay="300"> <el-tooltip :disabled="!scope.row.异常说明" effect="dark" placement="top" :open-delay="300">
<div slot="content" class="note-tooltip-content">{{ scope.row.异常说明 }}</div> <div slot="content" class="note-tooltip-content">{{ scope.row.异常说明 }}</div>
@@ -115,7 +122,7 @@
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="left" label="奇思妙想" prop="奇思妙想" width="240"> <el-table-column align="left" label="奇思妙想" prop="奇思妙想" width="360">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tooltip :disabled="!scope.row.奇思妙想" effect="dark" placement="top" :open-delay="300"> <el-tooltip :disabled="!scope.row.奇思妙想" effect="dark" placement="top" :open-delay="300">
<div slot="content" class="note-tooltip-content">{{ scope.row.奇思妙想 }}</div> <div slot="content" class="note-tooltip-content">{{ scope.row.奇思妙想 }}</div>
@@ -123,15 +130,30 @@
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="最后开始" prop="最后开始时间" width="150" /> <el-table-column align="left" label="项目号" prop="项目号" width="150" show-overflow-tooltip />
<el-table-column align="center" label="最后结束" prop="最后结束时间" width="150" /> <el-table-column align="left" label="物料编码" prop="物料编码" width="200" 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 />
<el-table-column align="center" fixed="right" label="操作" width="330"> <el-table-column align="left" label="图号" prop="图号" width="160" show-overflow-tooltip />
<el-table-column align="left" label="类别" prop="类别" width="170" show-overflow-tooltip />
<el-table-column align="left" label="任务来源" prop="任务来源" width="200" show-overflow-tooltip />
<el-table-column align="left" label="父件物料编码" prop="关联父件物料编码" width="200" show-overflow-tooltip />
<el-table-column align="left" label="研发立项号" prop="研发立项号" width="170" show-overflow-tooltip />
<el-table-column align="left" label="研发目的" prop="研发目的" width="280" show-overflow-tooltip />
<el-table-column align="left" label="对其可见" prop="对齐可见" width="220" show-overflow-tooltip />
<el-table-column align="center" label="报工次数" prop="报工次数" width="110" />
<el-table-column align="center" label="未结束" prop="未结束报工数" width="100" />
<el-table-column align="left" label="设计正在对应" prop="未结束报工人员" width="200" show-overflow-tooltip />
<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" label="最后开始" prop="最后开始时间" width="180" />
<el-table-column align="center" label="最后结束" prop="最后结束时间" width="180" />
<el-table-column align="center" fixed="right" label="操作" width="440">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="design-action-buttons"> <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="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 type="text" size="mini" :disabled="!canEnd(scope.row)" @click="endTask(scope.row)">结束</el-button>
<el-button type="text" size="mini" :disabled="!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" @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" @click="openNoteDialog(scope.row, '奇思妙想')">奇思妙想</el-button>
</div> </div>
@@ -219,7 +241,9 @@ export default {
actionLoading: false, actionLoading: false,
endDialogVisible: false, endDialogVisible: false,
noteDialogVisible: false, noteDialogVisible: false,
canUseLeaderInstruction: false,
tableData: [], tableData: [],
categoryOptions: ['实验', '研发', '方案评审', '售前', '售中', '订单', '售后信息确认', '售后问题指导', '售后物料准备', '返修品处理', '其他'],
projectOptions: [], projectOptions: [],
materialOptions: [], materialOptions: [],
parentMaterialOptions: [], parentMaterialOptions: [],
@@ -243,11 +267,13 @@ export default {
drawingNo: '', drawingNo: '',
parentItemCode: '', parentItemCode: '',
category: '', category: '',
status: '' taskSource: '',
status: '未完成'
} }
} }
}, },
created() { created() {
this.loadLeaderInstructionPermission()
this.loadDefaultProjectOptions() this.loadDefaultProjectOptions()
this.loadDefaultMaterialOptions() this.loadDefaultMaterialOptions()
this.searchTable() this.searchTable()
@@ -272,6 +298,7 @@ export default {
['物料编码', this.searchForm.itemCode || ''], ['物料编码', this.searchForm.itemCode || ''],
['图号', this.searchForm.drawingNo || ''], ['图号', this.searchForm.drawingNo || ''],
['类别', this.searchForm.category || ''], ['类别', this.searchForm.category || ''],
['任务来源', this.searchForm.taskSource || ''],
['关联父件物料编码', this.searchForm.parentItemCode || ''], ['关联父件物料编码', this.searchForm.parentItemCode || ''],
['预计开始时间_Start', ''], ['预计开始时间_Start', ''],
['预计开始时间_End', ''], ['预计开始时间_End', ''],
@@ -328,9 +355,6 @@ export default {
canStart(row) { canStart(row) {
return Number(row.当前用户未结束报工数 || 0) === 0 return Number(row.当前用户未结束报工数 || 0) === 0
}, },
canComplete(row) {
return row.单据状态 !== '已完成' && Number(row.报工次数 || 0) > 0
},
async startTask(row) { async startTask(row) {
const openTask = await this.getCurrentOpenTask() const openTask = await this.getCurrentOpenTask()
if (openTask === false) return if (openTask === false) return
@@ -398,36 +422,21 @@ export default {
['说明类型', this.noteForm.说明类型], ['说明类型', this.noteForm.说明类型],
['说明内容', content], ['说明内容', content],
['操作人ID', this.currentUserId()], ['操作人ID', this.currentUserId()],
['操作人', this.currentUserName()] ['操作人', this.currentUserName()],
['角色编号', this.currentRoleId()]
], '保存成功') ], '保存成功')
if (success) this.noteDialogVisible = false if (success) this.noteDialogVisible = false
}, },
async completeTask(row) { async loadLeaderInstructionPermission() {
const latest = await this.getLatestTask(row.DID) this.canUseLeaderInstruction = false
if (!latest) return const data = this.CreateData('11', '设计报工_领导批示权限_查询', [['角色编号', this.currentRoleId()]])
Object.assign(row, latest) try {
if (Number(latest.未结束报工数 || 0) > 0) { const response = await this.ExecDatabase(data)
const people = latest.未结束报工人员 || '有人员' const row = (response.data || [])[0] || {}
this.$message.warning(`${people} 还未点击结束,不能完成任务`) this.canUseLeaderInstruction = Number(row.有批示权限 || 0) === 1
return } catch (error) {
console.error('领导批示权限查询失败:', error)
} }
if (latest.单据状态 === '已完成') {
this.$message.warning('任务已完成')
this.searchTable()
return
}
if (!this.canComplete(latest)) {
this.$message.warning('任务未产生已结束报工,不能完成')
return
}
this.$confirm(`确定完成设计任务 DID ${latest.DID} 吗?`, '提示', { type: 'warning' })
.then(() => {
this.runAction('设计报工_任务_完成', [
['DID', latest.DID],
['操作人', this.currentUserName()]
], '完成成功')
})
.catch(() => {})
}, },
async getLatestTask(did) { async getLatestTask(did) {
const params = [ const params = [
@@ -436,6 +445,7 @@ export default {
['物料编码', ''], ['物料编码', ''],
['图号', ''], ['图号', ''],
['类别', ''], ['类别', ''],
['任务来源', ''],
['关联父件物料编码', ''], ['关联父件物料编码', ''],
['预计开始时间_Start', ''], ['预计开始时间_Start', ''],
['预计开始时间_End', ''], ['预计开始时间_End', ''],
@@ -468,6 +478,7 @@ export default {
['物料编码', ''], ['物料编码', ''],
['图号', ''], ['图号', ''],
['类别', ''], ['类别', ''],
['任务来源', ''],
['关联父件物料编码', ''], ['关联父件物料编码', ''],
['预计开始时间_Start', ''], ['预计开始时间_Start', ''],
['预计开始时间_End', ''], ['预计开始时间_End', ''],
@@ -522,6 +533,9 @@ export default {
currentUserName() { currentUserName() {
return (this.$store && this.$store.getters && this.$store.getters.name) || '' return (this.$store && this.$store.getters && this.$store.getters.name) || ''
}, },
currentRoleId() {
return (this.$store && this.$store.getters && this.$store.getters.token) || ''
},
formatMaterialLabel(item) { formatMaterialLabel(item) {
return item.物料名称 ? `${item.物料编码} | ${item.物料名称}` : item.物料编码 return item.物料名称 ? `${item.物料编码} | ${item.物料名称}` : item.物料编码
}, },
@@ -565,19 +579,55 @@ export default {
margin: 0; margin: 0;
padding: 0; padding: 0;
min-width: 32px; min-width: 32px;
font-size: 15px;
} }
.design-action-buttons ::v-deep .el-button + .el-button { .design-action-buttons ::v-deep .el-button + .el-button {
margin-left: 0; margin-left: 0;
} }
.design-data-table ::v-deep .el-table__header th {
height: 48px;
padding: 8px 0;
font-size: 15px;
}
.design-data-table ::v-deep .el-table__row,
.design-data-table ::v-deep .el-table__body td {
height: 108px;
}
.design-data-table ::v-deep .el-table__body td {
padding: 8px 0;
font-size: 16px;
}
.design-data-table ::v-deep .cell {
line-height: 24px;
}
.design-data-table ::v-deep .el-table__body .cell,
.design-data-table ::v-deep .el-table__body .cell.el-tooltip {
white-space: normal !important;
overflow: visible;
text-overflow: clip;
overflow-wrap: anywhere;
word-break: break-word;
}
.design-data-table ::v-deep .el-tag {
height: 30px;
line-height: 28px;
font-size: 14px;
}
.note-history { .note-history {
width: 100%; width: 100%;
min-height: 20px; min-height: 72px;
line-height: 20px; line-height: 24px;
white-space: nowrap; white-space: pre-line;
overflow: hidden; overflow: visible;
text-overflow: ellipsis; overflow-wrap: anywhere;
} }
.note-tooltip-content { .note-tooltip-content {

View File

@@ -55,10 +55,15 @@
/> />
</el-select> </el-select>
<span class="show-text">类别:</span> <span class="show-text">类别:</span>
<el-input v-model="searchForm.category" clearable size="small" style="width: 120px; margin-right: 8px" /> <el-select v-model="searchForm.category" clearable size="small" style="width: 150px; margin-right: 8px">
<el-option v-for="item in categoryOptions" :key="item" :label="item" :value="item" />
</el-select>
<span class="show-text">任务来源:</span>
<el-input v-model="searchForm.taskSource" clearable size="small" style="width: 140px; margin-right: 8px" />
<span class="show-text">状态:</span> <span class="show-text">状态:</span>
<el-select v-model="searchForm.status" clearable size="small" style="width: 110px; margin-right: 8px"> <el-select v-model="searchForm.status" clearable size="small" style="width: 110px; margin-right: 8px">
<el-option label="全部" value="全部" /> <el-option label="全部" value="全部" />
<el-option label="未完成" value="未完成" />
<el-option label="待开始" value="待开始" /> <el-option label="待开始" value="待开始" />
<el-option label="执行中" value="执行中" /> <el-option label="执行中" value="执行中" />
<el-option label="已结束" value="已结束" /> <el-option label="已结束" value="已结束" />
@@ -107,6 +112,7 @@
<el-table <el-table
v-loading="loading" v-loading="loading"
class="design-data-table"
:data="tableData" :data="tableData"
border border
height="70vh" height="70vh"
@@ -114,30 +120,26 @@
size="mini" size="mini"
style="width: 100%; margin-top: 12px" style="width: 100%; margin-top: 12px"
> >
<el-table-column align="center" fixed label="DID" prop="DID" width="70" /> <el-table-column align="left" fixed label="领导批示" prop="领导批示" width="360">
<el-table-column align="center" fixed label="状态" prop="单据状态" width="90"> <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" />
<el-table-column align="center" fixed label="状态" prop="单据状态" width="110">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag :type="getStatusType(scope.row.单据状态)" size="mini">{{ scope.row.单据状态 }}</el-tag> <el-tag :type="getStatusType(scope.row.单据状态)" size="mini">{{ scope.row.单据状态 }}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="left" label="项目号" prop="项目号" width="120" show-overflow-tooltip /> <el-table-column align="left" label="任务描述" prop="任务描述" width="320" show-overflow-tooltip />
<el-table-column align="left" label="物料编码" prop="物料编码" width="170" show-overflow-tooltip /> <el-table-column align="left" label="设计要求" prop="设计要求" width="320" show-overflow-tooltip />
<el-table-column align="left" label="物料名称" prop="物料名称" width="180" show-overflow-tooltip /> <el-table-column align="left" label="指派对象" prop="指派对象" width="220" show-overflow-tooltip />
<el-table-column align="left" label="图号" prop="图号" width="130" show-overflow-tooltip /> <el-table-column align="center" label="预计开始" prop="预计开始时间" width="180" />
<el-table-column align="left" label="类别" prop="类别" width="120" show-overflow-tooltip /> <el-table-column align="center" label="预计结束" prop="预计结束时间" width="180" />
<el-table-column align="left" label="任务描述" prop="任务描述" width="220" show-overflow-tooltip /> <el-table-column align="left" label="进度说明" prop="进度说明" width="360">
<el-table-column align="left" label="父件物料编码" prop="关联父件物料编码" width="160" show-overflow-tooltip />
<el-table-column align="left" label="设计要求" prop="设计要求" width="220" show-overflow-tooltip />
<el-table-column align="left" label="研发立项号" prop="研发立项号" width="130" show-overflow-tooltip />
<el-table-column align="left" label="研发目的" prop="研发目的" width="200" show-overflow-tooltip />
<el-table-column align="left" label="对其可见" prop="对齐可见" width="180" show-overflow-tooltip />
<el-table-column align="left" label="指派对象" prop="指派对象" width="180" show-overflow-tooltip />
<el-table-column align="center" label="预计开始" prop="预计开始时间" width="150" />
<el-table-column align="center" label="预计结束" prop="预计结束时间" width="150" />
<el-table-column align="center" label="报工次数" prop="报工次数" width="90" />
<el-table-column align="center" label="未结束" prop="未结束报工数" width="80" />
<el-table-column align="left" label="设计正在对应" prop="未结束报工人员" width="150" show-overflow-tooltip />
<el-table-column align="left" label="进度说明" prop="进度说明" width="240">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tooltip :disabled="!scope.row.进度说明" effect="dark" placement="top" :open-delay="300"> <el-tooltip :disabled="!scope.row.进度说明" effect="dark" placement="top" :open-delay="300">
<div slot="content" class="note-tooltip-content">{{ scope.row.进度说明 }}</div> <div slot="content" class="note-tooltip-content">{{ scope.row.进度说明 }}</div>
@@ -145,7 +147,7 @@
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="left" label="异常说明" prop="异常说明" width="240"> <el-table-column align="left" label="异常说明" prop="异常说明" width="360">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tooltip :disabled="!scope.row.异常说明" effect="dark" placement="top" :open-delay="300"> <el-tooltip :disabled="!scope.row.异常说明" effect="dark" placement="top" :open-delay="300">
<div slot="content" class="note-tooltip-content">{{ scope.row.异常说明 }}</div> <div slot="content" class="note-tooltip-content">{{ scope.row.异常说明 }}</div>
@@ -153,7 +155,7 @@
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="left" label="奇思妙想" prop="奇思妙想" width="240"> <el-table-column align="left" label="奇思妙想" prop="奇思妙想" width="360">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tooltip :disabled="!scope.row.奇思妙想" effect="dark" placement="top" :open-delay="300"> <el-tooltip :disabled="!scope.row.奇思妙想" effect="dark" placement="top" :open-delay="300">
<div slot="content" class="note-tooltip-content">{{ scope.row.奇思妙想 }}</div> <div slot="content" class="note-tooltip-content">{{ scope.row.奇思妙想 }}</div>
@@ -161,13 +163,30 @@
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="创建日期" prop="创建日期" width="150" /> <el-table-column align="left" label="项目号" prop="项目号" width="150" show-overflow-tooltip />
<el-table-column align="left" label="创建人" prop="创建人" width="110" show-overflow-tooltip /> <el-table-column align="left" label="物料编码" prop="物料编码" width="200" show-overflow-tooltip />
<el-table-column align="left" label="备注" prop="备注" width="180" show-overflow-tooltip /> <el-table-column align="left" label="物料名称" prop="物料名称" width="220" show-overflow-tooltip />
<el-table-column align="center" fixed="right" label="操作" width="150"> <el-table-column align="left" label="图号" prop="图号" width="160" show-overflow-tooltip />
<el-table-column align="left" label="类别" prop="类别" width="170" show-overflow-tooltip />
<el-table-column align="left" label="任务来源" prop="任务来源" width="200" show-overflow-tooltip />
<el-table-column align="left" label="父件物料编码" prop="关联父件物料编码" width="200" show-overflow-tooltip />
<el-table-column align="left" label="研发立项号" prop="研发立项号" width="170" show-overflow-tooltip />
<el-table-column align="left" label="研发目的" prop="研发目的" width="280" show-overflow-tooltip />
<el-table-column align="left" label="对其可见" prop="对齐可见" width="220" show-overflow-tooltip />
<el-table-column align="center" label="报工次数" prop="报工次数" width="110" />
<el-table-column align="center" label="未结束" prop="未结束报工数" width="100" />
<el-table-column align="left" label="设计正在对应" prop="未结束报工人员" width="200" show-overflow-tooltip />
<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="340">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="design-action-buttons"> <div class="design-action-buttons">
<el-button type="text" size="mini" @click="openEdit(scope.row)">编辑</el-button> <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" class="danger-action" @click="deleteTask(scope.row)">删除</el-button> <el-button type="text" size="mini" class="danger-action" @click="deleteTask(scope.row)">删除</el-button>
</div> </div>
</template> </template>
@@ -196,17 +215,24 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="类别"> <el-form-item label="类别">
<el-input v-model="formData.类别" /> <el-select v-model="formData.类别" clearable style="width: 100%">
<el-option v-for="item in categoryOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="任务来源">
<el-input v-model="formData.任务来源" maxlength="200" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="任务描述" prop="任务描述"> <el-form-item label="任务描述" prop="任务描述">
<el-input v-model="formData.任务描述" type="textarea" :rows="2" /> <el-input v-model="formData.任务描述" type="textarea" :rows="2" :disabled="isEdit && !isTaskCreator" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="设计要求"> <el-form-item label="设计要求">
<el-input v-model="formData.设计要求" type="textarea" :rows="3" /> <el-input v-model="formData.设计要求" type="textarea" :rows="3" :disabled="isEdit && !isTaskCreator" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="24"> <el-col :span="24">
@@ -357,6 +383,37 @@
<el-button type="primary" :loading="submitLoading" @click="submitForm">保存</el-button> <el-button type="primary" :loading="submitLoading" @click="submitForm">保存</el-button>
</div> </div>
</el-dialog> </el-dialog>
<el-dialog
:visible.sync="noteDialogVisible"
title="领导批示"
width="620px"
center
:close-on-click-modal="false"
>
<el-form :model="noteForm" label-width="100px" size="small">
<el-form-item label="DID">
<el-input v-model="noteForm.DID" disabled />
</el-form-item>
<el-form-item label="任务描述">
<el-input v-model="noteForm.任务描述" type="textarea" :rows="2" disabled />
</el-form-item>
<el-form-item label="领导批示">
<el-input
v-model="noteForm.说明内容"
type="textarea"
:rows="5"
maxlength="2000"
show-word-limit
placeholder="请输入领导批示"
/>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="noteDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="noteLoading" @click="confirmNote">保存</el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
@@ -366,15 +423,25 @@ export default {
data() { data() {
return { return {
loading: false, loading: false,
actionLoading: false,
submitLoading: false, submitLoading: false,
noteLoading: false,
dialogVisible: false, dialogVisible: false,
noteDialogVisible: false,
isEdit: false, isEdit: false,
canUseLeaderInstruction: false,
tableData: [], tableData: [],
categoryOptions: ['实验', '研发', '方案评审', '售前', '售中', '订单', '售后信息确认', '售后问题指导', '售后物料准备', '返修品处理', '其他'],
projectOptions: [], projectOptions: [],
materialOptions: [], materialOptions: [],
parentMaterialOptions: [], parentMaterialOptions: [],
personnelOptions: [], personnelOptions: [],
visibilityPersonnelOptions: [], visibilityPersonnelOptions: [],
noteForm: {
DID: '',
任务描述: '',
说明内容: ''
},
searchForm: { searchForm: {
did: '', did: '',
projectNo: '', projectNo: '',
@@ -382,11 +449,12 @@ export default {
drawingNo: '', drawingNo: '',
parentItemCode: '', parentItemCode: '',
category: '', category: '',
taskSource: '',
planStartFrom: '', planStartFrom: '',
planStartTo: '', planStartTo: '',
planEndFrom: '', planEndFrom: '',
planEndTo: '', planEndTo: '',
status: '' status: '未完成'
}, },
formData: this.getEmptyForm(), formData: this.getEmptyForm(),
rules: { rules: {
@@ -394,7 +462,13 @@ export default {
} }
} }
}, },
computed: {
isTaskCreator() {
return String(this.formData.创建人 || '').trim() === String(this.currentUserName() || '').trim()
}
},
created() { created() {
this.loadLeaderInstructionPermission()
this.loadDefaultProjectOptions() this.loadDefaultProjectOptions()
this.queryPersonnel('') this.queryPersonnel('')
this.queryVisibilityPersonnel('') this.queryVisibilityPersonnel('')
@@ -410,6 +484,7 @@ export default {
物料名称: '', 物料名称: '',
图号: '', 图号: '',
类别: '', 类别: '',
任务来源: '',
任务描述: '', 任务描述: '',
关联父件物料编码: '', 关联父件物料编码: '',
关联父件物料名称: '', 关联父件物料名称: '',
@@ -435,6 +510,7 @@ export default {
['物料编码', this.searchForm.itemCode || ''], ['物料编码', this.searchForm.itemCode || ''],
['图号', this.searchForm.drawingNo || ''], ['图号', this.searchForm.drawingNo || ''],
['类别', this.searchForm.category || ''], ['类别', this.searchForm.category || ''],
['任务来源', this.searchForm.taskSource || ''],
['关联父件物料编码', this.searchForm.parentItemCode || ''], ['关联父件物料编码', this.searchForm.parentItemCode || ''],
['预计开始时间_Start', this.searchForm.planStartFrom || ''], ['预计开始时间_Start', this.searchForm.planStartFrom || ''],
['预计开始时间_End', this.searchForm.planStartTo || ''], ['预计开始时间_End', this.searchForm.planStartTo || ''],
@@ -484,6 +560,57 @@ export default {
this.dialogVisible = true this.dialogVisible = true
this.$nextTick(() => this.$refs.taskForm && this.$refs.taskForm.clearValidate()) this.$nextTick(() => this.$refs.taskForm && this.$refs.taskForm.clearValidate())
}, },
openNoteDialog(row) {
this.noteForm = {
DID: row.DID,
任务描述: row.任务描述 || '',
说明内容: ''
}
this.noteDialogVisible = true
},
async confirmNote() {
const content = String(this.noteForm.说明内容 || '').trim()
if (!content) {
this.$message.warning('请输入领导批示')
return
}
this.noteLoading = true
const data = this.CreateData('12', '设计报工_任务说明_新增', [
['DID', this.noteForm.DID],
['说明类型', '领导批示'],
['说明内容', content],
['操作人ID', this.currentUserId()],
['操作人', this.currentUserName()],
['角色编号', this.currentRoleId()]
])
try {
const response = await this.ExecDatabase(data)
const result = this.getResult(response)
if (String(result.result) === '1') {
this.$message.success(result.message || '保存成功')
this.noteDialogVisible = false
this.searchTable()
} else {
this.$message.error(result.message || '保存失败')
}
} catch (error) {
console.error('领导批示保存失败:', error)
this.$message.error('保存失败')
} finally {
this.noteLoading = false
}
},
async loadLeaderInstructionPermission() {
this.canUseLeaderInstruction = false
const data = this.CreateData('11', '设计报工_领导批示权限_查询', [['角色编号', this.currentRoleId()]])
try {
const response = await this.ExecDatabase(data)
const row = (response.data || [])[0] || {}
this.canUseLeaderInstruction = Number(row.有批示权限 || 0) === 1
} catch (error) {
console.error('领导批示权限查询失败:', error)
}
},
loadDefaultProjectOptions() { loadDefaultProjectOptions() {
this.queryProjects('') this.queryProjects('')
}, },
@@ -529,6 +656,7 @@ export default {
params.push(['物料名称', this.formData.物料名称 || '']) params.push(['物料名称', this.formData.物料名称 || ''])
params.push(['图号', this.formData.图号 || '']) params.push(['图号', this.formData.图号 || ''])
params.push(['类别', this.formData.类别 || '']) params.push(['类别', this.formData.类别 || ''])
params.push(['任务来源', this.formData.任务来源 || ''])
params.push(['任务描述', this.formData.任务描述 || '']) params.push(['任务描述', this.formData.任务描述 || ''])
params.push(['关联父件物料编码', this.formData.关联父件物料编码 || '']) params.push(['关联父件物料编码', this.formData.关联父件物料编码 || ''])
params.push(['关联父件物料名称', this.formData.关联父件物料名称 || '']) params.push(['关联父件物料名称', this.formData.关联父件物料名称 || ''])
@@ -574,6 +702,36 @@ export default {
}) })
.catch(() => {}) .catch(() => {})
}, },
canComplete(row) {
return row.单据状态 !== '已完成' && Number(row.报工次数 || 0) > 0
},
async completeTask(row) {
const latest = await this.getLatestTask(row.DID)
if (!latest) return
Object.assign(row, latest)
if (Number(latest.未结束报工数 || 0) > 0) {
const people = latest.未结束报工人员 || '有人员'
this.$message.warning(`${people} 还未点击结束,不能完成任务`)
return
}
if (latest.单据状态 === '已完成') {
this.$message.warning('任务已完成')
this.searchTable()
return
}
if (!this.canComplete(latest)) {
this.$message.warning('任务未产生已结束报工,不能完成')
return
}
this.$confirm(`确定完成设计任务 DID ${latest.DID} 吗?`, '提示', { type: 'warning' })
.then(() => {
this.runAction('设计报工_任务_完成', [
['DID', latest.DID],
['操作人', this.currentUserName()]
], '完成成功')
})
.catch(() => {})
},
async getLatestTask(did) { async getLatestTask(did) {
const params = [ const params = [
['DID', did || 0], ['DID', did || 0],
@@ -581,6 +739,7 @@ export default {
['物料编码', ''], ['物料编码', ''],
['图号', ''], ['图号', ''],
['类别', ''], ['类别', ''],
['任务来源', ''],
['关联父件物料编码', ''], ['关联父件物料编码', ''],
['预计开始时间_Start', ''], ['预计开始时间_Start', ''],
['预计开始时间_End', ''], ['预计开始时间_End', ''],
@@ -593,17 +752,39 @@ export default {
const response = await this.ExecDatabase(data) const response = await this.ExecDatabase(data)
const rows = response.data || [] const rows = response.data || []
if (rows.length === 0) { if (rows.length === 0) {
this.$message.error('删除失败:任务不存在或已被删除') this.$message.error('任务不存在或已被删除')
this.searchTable() this.searchTable()
return null return null
} }
return rows[0] return rows[0]
} catch (error) { } catch (error) {
console.error('设计任务删除前查询失败:', error) console.error('设计任务实时查询失败:', error)
this.$message.error('删除失败') this.$message.error('操作前查询失败')
return null return null
} }
}, },
async runAction(procedure, params, defaultMessage) {
if (this.actionLoading) return false
this.actionLoading = true
const data = this.CreateData('12', procedure, params)
try {
const response = await this.ExecDatabase(data)
const result = this.getResult(response)
if (String(result.result) === '1') {
this.$message.success(result.message || defaultMessage)
this.searchTable()
return true
}
this.$message.error(result.message || '操作失败')
return false
} catch (error) {
console.error(`${procedure}失败:`, error)
this.$message.error('操作失败')
return false
} finally {
this.actionLoading = false
}
},
getDeleteBlockMessage(row) { getDeleteBlockMessage(row) {
if (Number(row.报工次数 || 0) > 0) return '删除失败:该任务已有设计报工记录,不能删除' if (Number(row.报工次数 || 0) > 0) return '删除失败:该任务已有设计报工记录,不能删除'
if (row.单据状态 === '已完成') return '删除失败:任务已完成,不能删除' if (row.单据状态 === '已完成') return '删除失败:任务已完成,不能删除'
@@ -703,6 +884,12 @@ export default {
currentUserName() { currentUserName() {
return (this.$store && this.$store.getters && this.$store.getters.name) || '' return (this.$store && this.$store.getters && this.$store.getters.name) || ''
}, },
currentUserId() {
return (this.$store && this.$store.getters && this.$store.getters.id) || ''
},
currentRoleId() {
return (this.$store && this.$store.getters && this.$store.getters.token) || ''
},
getStatusType(status) { getStatusType(status) {
if (status === '已完成') return 'success' if (status === '已完成') return 'success'
if (status === '执行中') return 'warning' if (status === '执行中') return 'warning'
@@ -745,6 +932,7 @@ export default {
margin: 0; margin: 0;
padding: 0; padding: 0;
min-width: 32px; min-width: 32px;
font-size: 15px;
} }
.design-action-buttons ::v-deep .el-button + .el-button { .design-action-buttons ::v-deep .el-button + .el-button {
@@ -755,13 +943,48 @@ export default {
color: #f56c6c; color: #f56c6c;
} }
.design-data-table ::v-deep .el-table__header th {
height: 48px;
padding: 8px 0;
font-size: 15px;
}
.design-data-table ::v-deep .el-table__row,
.design-data-table ::v-deep .el-table__body td {
height: 108px;
}
.design-data-table ::v-deep .el-table__body td {
padding: 8px 0;
font-size: 16px;
}
.design-data-table ::v-deep .cell {
line-height: 24px;
}
.design-data-table ::v-deep .el-table__body .cell,
.design-data-table ::v-deep .el-table__body .cell.el-tooltip {
white-space: normal !important;
overflow: visible;
text-overflow: clip;
overflow-wrap: anywhere;
word-break: break-word;
}
.design-data-table ::v-deep .el-tag {
height: 30px;
line-height: 28px;
font-size: 14px;
}
.note-history { .note-history {
width: 100%; width: 100%;
min-height: 20px; min-height: 72px;
line-height: 20px; line-height: 24px;
white-space: nowrap; white-space: pre-line;
overflow: hidden; overflow: visible;
text-overflow: ellipsis; overflow-wrap: anywhere;
} }
.note-tooltip-content { .note-tooltip-content {

View File

@@ -233,13 +233,13 @@
@change="calculateWorkTime" /> @change="calculateWorkTime" />
</el-form-item> </el-form-item>
<el-form-item label="加工工时"> <el-form-item label="设备工时">
<el-input v-model="editForm.加工工时" readonly> <el-input v-model="editForm.加工工时" >
<template slot="append"></template> <template slot="append"></template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item label="人员工时"> <el-form-item label="人员工时">
<el-input v-model="editForm.总时长" readonly> <el-input v-model="editForm.总时长" >
<template slot="append"></template> <template slot="append"></template>
</el-input> </el-input>
</el-form-item> </el-form-item>
@@ -1675,11 +1675,13 @@ async addPersonnelTimeSheet3(data, order, stageId, workHours, params, isAssistan
// 更新数据库校验状态 // 更新数据库校验状态
async updateValidationStatus(data) { async updateValidationStatus(data) {
var 总时长 = this.editForm.总时长 var 总时长 = this.editForm.总时长
var 加工工时 = this.editForm.加工工时
var param = [ var param = [
['orderAID', this.currentTask.AID], ['orderAID', this.currentTask.AID],
['开始时间', this.editForm.开始时间], ['开始时间', this.editForm.开始时间],
['结束时间', this.editForm.结束时间], ['结束时间', this.editForm.结束时间],
['总时长', 总时长], ['总时长', 总时长],
['加工工时', 加工工时],
['操作人', this.getCurrentUser()], ['操作人', this.getCurrentUser()],
['最后编辑人', this.getCurrentUser()], ['最后编辑人', this.getCurrentUser()],
['当日班次最小标准工时', this.editForm.当日班次最小标准工时] ['当日班次最小标准工时', this.editForm.当日班次最小标准工时]

View File

@@ -204,13 +204,13 @@
@change="calculateWorkTime" /> @change="calculateWorkTime" />
</el-form-item> </el-form-item>
<!-- <el-form-item label="加工工时"> <el-form-item label="设备工时">
<el-input v-model="editForm.加工工时" readonly> <el-input v-model="editForm.加工工时" >
<template slot="append"></template> <template slot="append"></template>
</el-input> </el-input>
</el-form-item> --> </el-form-item>
<el-form-item label="人员工时"> <el-form-item label="人员工时">
<el-input v-model="editForm.总时长" readonly> <el-input v-model="editForm.总时长" >
<template slot="append"></template> <template slot="append"></template>
</el-input> </el-input>
</el-form-item> </el-form-item>
@@ -706,11 +706,11 @@ export default {
this.editSubmitLoading = true this.editSubmitLoading = true
try { try {
await this.updateValidationStatus(this.editForm) await this.updateValidationStatus(this.editForm)
this.$message.success('校验成功') this.$message.success('修改成功')
this.editDialogVisible = false this.editDialogVisible = false
this.searchTable() this.searchTable()
} catch (error) { } catch (error) {
this.$message.error('校验失败:' + error.message) this.$message.error('修改失败:' + error.message)
} finally { } finally {
this.editSubmitLoading = false this.editSubmitLoading = false
} }
@@ -732,6 +732,7 @@ export default {
['开始时间', this.editForm.开始时间], ['开始时间', this.editForm.开始时间],
['结束时间', this.editForm.结束时间], ['结束时间', this.editForm.结束时间],
['总时长', 总时长], ['总时长', 总时长],
['加工工时', 加工工时],
['操作人', this.getCurrentUser()], ['操作人', this.getCurrentUser()],
['最后编辑人', this.getCurrentUser()], ['最后编辑人', this.getCurrentUser()],
['当日班次最小标准工时', this.editForm.当日班次最小标准工时] ['当日班次最小标准工时', this.editForm.当日班次最小标准工时]