diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js index d6df2e3d..129ce141 100644 --- a/build/webpack.base.conf.js +++ b/build/webpack.base.conf.js @@ -1,5 +1,6 @@ 'use strict' const path = require('path') +const webpack = require('webpack') const utils = require('./utils') const config = require('../config') const { VueLoaderPlugin } = require('vue-loader') @@ -95,7 +96,12 @@ module.exports = { } ] }, - plugins: [new VueLoaderPlugin()], + plugins: [ + new VueLoaderPlugin(), + // 修改人:Ld 修改时间:2026-08-05 08:13:25; xlsx-style 的 cpexcel 会引用缺失的 cptable,导出 xlsx 时替换为本地兼容模块。 + new webpack.NormalModuleReplacementPlugin(/^\.\/cptable$/, resolve('src/vendor/xlsx-style-cptable.js')), + new webpack.IgnorePlugin(/^\.\/cptable$/) + ], node: { // prevent webpack from injecting useless setImmediate polyfill because Vue // source contains it (although only uses it if it's native). diff --git a/sql/ERP_MES_PLM_QMS_WMS_APS_一级菜单_测试库_20260806.sql b/sql/ERP_MES_PLM_QMS_WMS_APS_一级菜单_测试库_20260806.sql new file mode 100644 index 00000000..6dc7c336 --- /dev/null +++ b/sql/ERP_MES_PLM_QMS_WMS_APS_一级菜单_测试库_20260806.sql @@ -0,0 +1,592 @@ +/* 修改人:Ld 修改时间:2026-08-06 09:50:27; 在测试库新增ERP经营管理、MES制造执行、PLM产品生产周期、QMS质量管理、WMS仓储管理、APS计划排产一级菜单,并给系统管理角色2追加权限 */ +SET XACT_ABORT ON; +BEGIN TRAN; + +DECLARE @RoleId INT = 2; +DECLARE @ModuleId INT; + +/* ERP经营管理 */ +SET @ModuleId = NULL; +SELECT @ModuleId = id +FROM dbo.基础表_模块信息 +WHERE title = N'ERP经营管理' + AND [path] = N'/'; + +IF @ModuleId IS NULL +BEGIN + INSERT INTO dbo.基础表_模块信息 + ( + [path], + component, + redirect, + name, + title, + icon, + 是否通知, + 消息通知来源, + 通知条件, + dashboardIcon, + 是否禁用 + ) + VALUES + ( + N'/', + N'/layout/Layout', + NULL, + N'ERPManagement', + N'ERP经营管理', + N'SystemRrolemaintenance', + NULL, + NULL, + NULL, + NULL, + 0 + ); + + SET @ModuleId = SCOPE_IDENTITY(); +END +ELSE +BEGIN + UPDATE dbo.基础表_模块信息 + SET component = N'/layout/Layout', + redirect = NULL, + name = N'ERPManagement', + title = N'ERP经营管理', + icon = N'SystemRrolemaintenance', + 是否禁用 = 0 + WHERE id = @ModuleId; +END; + +IF NOT EXISTS +( + SELECT 1 + FROM dbo.基础表_角色模块信息 + WHERE id = @ModuleId + AND pid = 0 + AND 角色编号 = @RoleId +) +BEGIN + INSERT INTO dbo.基础表_角色模块信息 + ( + id, + pid, + 模块顺序, + 角色编号, + 是否启用, + 角色模块顺序 + ) + SELECT + @ModuleId, + 0, + @ModuleId, + @RoleId, + 1, + ISNULL(MAX(角色模块顺序), 0) + 1 + FROM dbo.基础表_角色模块信息 + WHERE 角色编号 = @RoleId + AND pid = 0; +END +ELSE +BEGIN + UPDATE dbo.基础表_角色模块信息 + SET 是否启用 = 1 + WHERE id = @ModuleId + AND pid = 0 + AND 角色编号 = @RoleId; +END; + +/* MES制造执行 */ +SET @ModuleId = NULL; +SELECT @ModuleId = id +FROM dbo.基础表_模块信息 +WHERE title = N'MES制造执行' + AND [path] = N'/'; + +IF @ModuleId IS NULL +BEGIN + INSERT INTO dbo.基础表_模块信息 + ( + [path], + component, + redirect, + name, + title, + icon, + 是否通知, + 消息通知来源, + 通知条件, + dashboardIcon, + 是否禁用 + ) + VALUES + ( + N'/', + N'/layout/Layout', + NULL, + N'MESExecution', + N'MES制造执行', + N'车间', + NULL, + NULL, + NULL, + NULL, + 0 + ); + + SET @ModuleId = SCOPE_IDENTITY(); +END +ELSE +BEGIN + UPDATE dbo.基础表_模块信息 + SET component = N'/layout/Layout', + redirect = NULL, + name = N'MESExecution', + title = N'MES制造执行', + icon = N'车间', + 是否禁用 = 0 + WHERE id = @ModuleId; +END; + +IF NOT EXISTS +( + SELECT 1 + FROM dbo.基础表_角色模块信息 + WHERE id = @ModuleId + AND pid = 0 + AND 角色编号 = @RoleId +) +BEGIN + INSERT INTO dbo.基础表_角色模块信息 + ( + id, + pid, + 模块顺序, + 角色编号, + 是否启用, + 角色模块顺序 + ) + SELECT + @ModuleId, + 0, + @ModuleId, + @RoleId, + 1, + ISNULL(MAX(角色模块顺序), 0) + 1 + FROM dbo.基础表_角色模块信息 + WHERE 角色编号 = @RoleId + AND pid = 0; +END +ELSE +BEGIN + UPDATE dbo.基础表_角色模块信息 + SET 是否启用 = 1 + WHERE id = @ModuleId + AND pid = 0 + AND 角色编号 = @RoleId; +END; + +/* PLM产品生产周期 */ +SET @ModuleId = NULL; +SELECT @ModuleId = id +FROM dbo.基础表_模块信息 +WHERE title = N'PLM产品生产周期' + AND [path] = N'/'; + +IF @ModuleId IS NULL +BEGIN + INSERT INTO dbo.基础表_模块信息 + ( + [path], + component, + redirect, + name, + title, + icon, + 是否通知, + 消息通知来源, + 通知条件, + dashboardIcon, + 是否禁用 + ) + VALUES + ( + N'/', + N'/layout/Layout', + NULL, + N'PLMProductLifecycle', + N'PLM产品生产周期', + N'ProductMaintenance', + NULL, + NULL, + NULL, + NULL, + 0 + ); + + SET @ModuleId = SCOPE_IDENTITY(); +END +ELSE +BEGIN + UPDATE dbo.基础表_模块信息 + SET component = N'/layout/Layout', + redirect = NULL, + name = N'PLMProductLifecycle', + title = N'PLM产品生产周期', + icon = N'ProductMaintenance', + 是否禁用 = 0 + WHERE id = @ModuleId; +END; + +IF NOT EXISTS +( + SELECT 1 + FROM dbo.基础表_角色模块信息 + WHERE id = @ModuleId + AND pid = 0 + AND 角色编号 = @RoleId +) +BEGIN + INSERT INTO dbo.基础表_角色模块信息 + ( + id, + pid, + 模块顺序, + 角色编号, + 是否启用, + 角色模块顺序 + ) + SELECT + @ModuleId, + 0, + @ModuleId, + @RoleId, + 1, + ISNULL(MAX(角色模块顺序), 0) + 1 + FROM dbo.基础表_角色模块信息 + WHERE 角色编号 = @RoleId + AND pid = 0; +END +ELSE +BEGIN + UPDATE dbo.基础表_角色模块信息 + SET 是否启用 = 1 + WHERE id = @ModuleId + AND pid = 0 + AND 角色编号 = @RoleId; +END; + +/* QMS质量管理 */ +SET @ModuleId = NULL; +SELECT @ModuleId = id +FROM dbo.基础表_模块信息 +WHERE title = N'QMS质量管理' + AND [path] = N'/'; + +IF @ModuleId IS NULL +BEGIN + INSERT INTO dbo.基础表_模块信息 + ( + [path], + component, + redirect, + name, + title, + icon, + 是否通知, + 消息通知来源, + 通知条件, + dashboardIcon, + 是否禁用 + ) + VALUES + ( + N'/', + N'/layout/Layout', + NULL, + N'QMSQualityManagement', + N'QMS质量管理', + N'QualityInspectionQuery', + NULL, + NULL, + NULL, + NULL, + 0 + ); + + SET @ModuleId = SCOPE_IDENTITY(); +END +ELSE +BEGIN + UPDATE dbo.基础表_模块信息 + SET component = N'/layout/Layout', + redirect = NULL, + name = N'QMSQualityManagement', + title = N'QMS质量管理', + icon = N'QualityInspectionQuery', + 是否禁用 = 0 + WHERE id = @ModuleId; +END; + +IF NOT EXISTS +( + SELECT 1 + FROM dbo.基础表_角色模块信息 + WHERE id = @ModuleId + AND pid = 0 + AND 角色编号 = @RoleId +) +BEGIN + INSERT INTO dbo.基础表_角色模块信息 + ( + id, + pid, + 模块顺序, + 角色编号, + 是否启用, + 角色模块顺序 + ) + SELECT + @ModuleId, + 0, + @ModuleId, + @RoleId, + 1, + ISNULL(MAX(角色模块顺序), 0) + 1 + FROM dbo.基础表_角色模块信息 + WHERE 角色编号 = @RoleId + AND pid = 0; +END +ELSE +BEGIN + UPDATE dbo.基础表_角色模块信息 + SET 是否启用 = 1 + WHERE id = @ModuleId + AND pid = 0 + AND 角色编号 = @RoleId; +END; + +/* WMS仓储管理 */ +SET @ModuleId = NULL; +SELECT @ModuleId = id +FROM dbo.基础表_模块信息 +WHERE title = N'WMS仓储管理' + AND [path] = N'/'; + +IF @ModuleId IS NULL +BEGIN + INSERT INTO dbo.基础表_模块信息 + ( + [path], + component, + redirect, + name, + title, + icon, + 是否通知, + 消息通知来源, + 通知条件, + dashboardIcon, + 是否禁用 + ) + VALUES + ( + N'/', + N'/layout/Layout', + NULL, + N'WMSWarehouseManagement', + N'WMS仓储管理', + N'仓储管理', + NULL, + NULL, + NULL, + NULL, + 0 + ); + + SET @ModuleId = SCOPE_IDENTITY(); +END +ELSE +BEGIN + UPDATE dbo.基础表_模块信息 + SET component = N'/layout/Layout', + redirect = NULL, + name = N'WMSWarehouseManagement', + title = N'WMS仓储管理', + icon = N'仓储管理', + 是否禁用 = 0 + WHERE id = @ModuleId; +END; + +IF NOT EXISTS +( + SELECT 1 + FROM dbo.基础表_角色模块信息 + WHERE id = @ModuleId + AND pid = 0 + AND 角色编号 = @RoleId +) +BEGIN + INSERT INTO dbo.基础表_角色模块信息 + ( + id, + pid, + 模块顺序, + 角色编号, + 是否启用, + 角色模块顺序 + ) + SELECT + @ModuleId, + 0, + @ModuleId, + @RoleId, + 1, + ISNULL(MAX(角色模块顺序), 0) + 1 + FROM dbo.基础表_角色模块信息 + WHERE 角色编号 = @RoleId + AND pid = 0; +END +ELSE +BEGIN + UPDATE dbo.基础表_角色模块信息 + SET 是否启用 = 1 + WHERE id = @ModuleId + AND pid = 0 + AND 角色编号 = @RoleId; +END; + +/* APS计划排产 */ +SET @ModuleId = NULL; +SELECT @ModuleId = id +FROM dbo.基础表_模块信息 +WHERE title = N'APS计划排产' + AND [path] = N'/'; + +IF @ModuleId IS NULL +BEGIN + INSERT INTO dbo.基础表_模块信息 + ( + [path], + component, + redirect, + name, + title, + icon, + 是否通知, + 消息通知来源, + 通知条件, + dashboardIcon, + 是否禁用 + ) + VALUES + ( + N'/', + N'/layout/Layout', + NULL, + N'APSPlanScheduling', + N'APS计划排产', + N'ShopScheduling', + NULL, + NULL, + NULL, + NULL, + 0 + ); + + SET @ModuleId = SCOPE_IDENTITY(); +END +ELSE +BEGIN + UPDATE dbo.基础表_模块信息 + SET component = N'/layout/Layout', + redirect = NULL, + name = N'APSPlanScheduling', + title = N'APS计划排产', + icon = N'ShopScheduling', + 是否禁用 = 0 + WHERE id = @ModuleId; +END; + +IF NOT EXISTS +( + SELECT 1 + FROM dbo.基础表_角色模块信息 + WHERE id = @ModuleId + AND pid = 0 + AND 角色编号 = @RoleId +) +BEGIN + INSERT INTO dbo.基础表_角色模块信息 + ( + id, + pid, + 模块顺序, + 角色编号, + 是否启用, + 角色模块顺序 + ) + SELECT + @ModuleId, + 0, + @ModuleId, + @RoleId, + 1, + ISNULL(MAX(角色模块顺序), 0) + 1 + FROM dbo.基础表_角色模块信息 + WHERE 角色编号 = @RoleId + AND pid = 0; +END +ELSE +BEGIN + UPDATE dbo.基础表_角色模块信息 + SET 是否启用 = 1 + WHERE id = @ModuleId + AND pid = 0 + AND 角色编号 = @RoleId; +END; + +/* 修改人:Ld 修改时间:2026-08-06 09:50:27; 固定系统管理角色2下新增一级菜单的显示顺序 */ +DECLARE @BaseRoleOrder INT; + +SELECT @BaseRoleOrder = ISNULL(MAX(r.角色模块顺序), 0) +FROM dbo.基础表_角色模块信息 r +INNER JOIN dbo.基础表_模块信息 m ON m.id = r.id +WHERE r.角色编号 = @RoleId + AND r.pid = 0 + AND m.title NOT IN (N'ERP经营管理', N'MES制造执行', N'PLM产品生产周期', N'QMS质量管理', N'WMS仓储管理', N'APS计划排产'); + +;WITH MenuOrder AS +( + SELECT N'ERP经营管理' AS title, 1 AS SortNo + UNION ALL SELECT N'MES制造执行', 2 + UNION ALL SELECT N'PLM产品生产周期', 3 + UNION ALL SELECT N'QMS质量管理', 4 + UNION ALL SELECT N'WMS仓储管理', 5 + UNION ALL SELECT N'APS计划排产', 6 +) +UPDATE r +SET 角色模块顺序 = @BaseRoleOrder + MenuOrder.SortNo, + 是否启用 = 1 +FROM dbo.基础表_角色模块信息 r +INNER JOIN dbo.基础表_模块信息 m ON m.id = r.id +INNER JOIN MenuOrder ON MenuOrder.title = m.title +WHERE r.角色编号 = @RoleId + AND r.pid = 0; + +SELECT id, [path], component, name, title, icon, 是否禁用 +FROM dbo.基础表_模块信息 +WHERE title IN (N'ERP经营管理', N'MES制造执行', N'PLM产品生产周期', N'QMS质量管理', N'WMS仓储管理', N'APS计划排产') +ORDER BY id; + +SELECT id, pid, 模块顺序, 角色编号, 是否启用, 角色模块顺序 +FROM dbo.基础表_角色模块信息 +WHERE id IN +( + SELECT id + FROM dbo.基础表_模块信息 + WHERE title IN (N'ERP经营管理', N'MES制造执行', N'PLM产品生产周期', N'QMS质量管理', N'WMS仓储管理', N'APS计划排产') +) + AND pid = 0 +ORDER BY 角色编号, 角色模块顺序, id; + +COMMIT TRAN; diff --git a/sql/一级菜单二级组件迁移_测试库_20260806.sql b/sql/一级菜单二级组件迁移_测试库_20260806.sql new file mode 100644 index 00000000..09a08794 --- /dev/null +++ b/sql/一级菜单二级组件迁移_测试库_20260806.sql @@ -0,0 +1,140 @@ +/* 修改人:Ld 修改时间:2026-08-06 15:22:59; 将测试库角色2下可明确归属的二级组件迁移到新一级菜单下 */ +SET XACT_ABORT ON; +BEGIN TRAN; + +DECLARE @MoveMap TABLE +( + id INT PRIMARY KEY, + 目标pid INT NOT NULL, + 顺序 INT NOT NULL +); + +INSERT INTO @MoveMap (id, 目标pid, 顺序) +VALUES +(67, 160, 1), +(11, 160, 2), +(12, 160, 3), +(13, 160, 4), +(14, 160, 5), +(147, 160, 6), +(68, 160, 7), +(17, 160, 8), +(16, 160, 9), +(18, 160, 10), +(81, 160, 11), +(19, 160, 12), +(15, 160, 13), +(99, 160, 14), +(86, 160, 15), +(87, 160, 16), +(108, 160, 17), +(114, 160, 18), +(120, 160, 19), +(82, 160, 20), +(129, 160, 21), +(155, 160, 22), +(156, 160, 23), +(35, 160, 24), +(36, 160, 25), +(37, 160, 26), +(41, 160, 27), +(124, 160, 28), +(157, 160, 29), +(94, 161, 1), +(78, 161, 2), +(28, 161, 3), +(98, 161, 4), +(80, 161, 5), +(29, 161, 6), +(79, 161, 7), +(30, 161, 8), +(100, 161, 9), +(84, 161, 10), +(95, 161, 11), +(153, 161, 12), +(154, 161, 13), +(25, 162, 1), +(69, 162, 2), +(24, 162, 3), +(102, 162, 4), +(21, 162, 5), +(22, 162, 6), +(23, 162, 7), +(117, 162, 8), +(134, 162, 9), +(150, 162, 10), +(104, 163, 1), +(110, 163, 2), +(103, 163, 3), +(121, 163, 4), +(128, 163, 5), +(131, 163, 6), +(135, 163, 7), +(43, 164, 1), +(112, 164, 2), +(44, 164, 3), +(46, 164, 4), +(47, 164, 5), +(48, 164, 6), +(49, 164, 7), +(75, 164, 8), +(51, 164, 9), +(76, 164, 10), +(77, 164, 11), +(50, 164, 12), +(92, 164, 13), +(93, 164, 14), +(96, 164, 15), +(118, 164, 16), +(122, 164, 17), +(123, 164, 18), +(130, 164, 19), +(138, 164, 20), +(143, 164, 21), +(151, 164, 22), +(158, 164, 23), +(45, 164, 24), +(132, 159, 1); + +DECLARE @PidOrder TABLE +( + pid INT PRIMARY KEY, + 基础序号 INT NOT NULL +); + +INSERT INTO @PidOrder (pid, 基础序号) +SELECT + m.目标pid, + ISNULL(MAX(r.角色模块顺序), 0) AS 基础序号 +FROM @MoveMap m +LEFT JOIN dbo.基础表_角色模块信息 r + ON r.pid = m.目标pid + AND r.角色编号 = 2 + AND ISNULL(r.是否启用, 1) = 1 + AND NOT EXISTS + ( + SELECT 1 + FROM @MoveMap mm + WHERE mm.id = r.id + ) +GROUP BY m.目标pid; + +UPDATE r +SET r.pid = m.目标pid, + r.模块顺序 = r.id, + r.是否启用 = 1, + r.角色模块顺序 = p.基础序号 + m.顺序 +FROM dbo.基础表_角色模块信息 r +INNER JOIN @MoveMap m + ON m.id = r.id +INNER JOIN @PidOrder p + ON p.pid = m.目标pid +WHERE r.角色编号 = 2; + +SELECT p.title AS 新一级菜单, m.id AS 二级ID, m.目标pid, m.顺序, r.角色模块顺序 +FROM @MoveMap m +INNER JOIN dbo.基础表_模块信息 p ON p.id = m.目标pid +INNER JOIN dbo.基础表_角色模块信息 r ON r.id = m.id AND r.角色编号 = 2 +ORDER BY m.目标pid, r.角色模块顺序, m.id; + +COMMIT TRAN; diff --git a/sql/二级组件迁移结果修正_测试库_20260806.sql b/sql/二级组件迁移结果修正_测试库_20260806.sql new file mode 100644 index 00000000..1fd32553 --- /dev/null +++ b/sql/二级组件迁移结果修正_测试库_20260806.sql @@ -0,0 +1,34 @@ +/* 修改人:Ld 修改时间:2026-08-06 16:15:15; 精确修正角色2新一级菜单下误迁的占位授权记录 */ +SET XACT_ABORT ON; +BEGIN TRAN; + +UPDATE dbo.基础表_角色模块信息 +SET pid = 161, + 是否启用 = 1, + 角色模块顺序 = CASE IDD + WHEN 1184 THEN 1 + WHEN 1181 THEN 3 + WHEN 1183 THEN 10 + WHEN 1185 THEN 11 + WHEN 1187 THEN 12 + WHEN 1182 THEN 7 + WHEN 1186 THEN 13 + ELSE 角色模块顺序 + END +WHERE 角色编号 = 2 + AND IDD IN (1184, 1181, 1183, 1185, 1187, 1182, 1186); + +UPDATE dbo.基础表_角色模块信息 +SET 是否启用 = 0 +WHERE 角色编号 = 2 + AND IDD = 1177; + +SELECT p.title AS 一级菜单, c.id AS 二级ID, c.title AS 二级菜单, r.IDD, r.是否启用, r.角色模块顺序 +FROM dbo.基础表_角色模块信息 r +INNER JOIN dbo.基础表_模块信息 c ON c.id = r.id +LEFT JOIN dbo.基础表_模块信息 p ON p.id = r.pid +WHERE r.角色编号 = 2 + AND r.IDD IN (1184, 1181, 1183, 1185, 1187, 1182, 1186, 1177) +ORDER BY r.是否启用 DESC, p.id, r.角色模块顺序, c.id; + +COMMIT TRAN; diff --git a/sql/二级组件迁移顺序与缺项修正_测试库_20260806.sql b/sql/二级组件迁移顺序与缺项修正_测试库_20260806.sql new file mode 100644 index 00000000..87e240ef --- /dev/null +++ b/sql/二级组件迁移顺序与缺项修正_测试库_20260806.sql @@ -0,0 +1,199 @@ +/* 修改人:Ld 修改时间:2026-08-06 16:15:15; 补回建议清单缺项并重排角色2新一级菜单下二级组件顺序 */ +SET XACT_ABORT ON; +BEGIN TRAN; + +IF NOT EXISTS +( + SELECT 1 + FROM dbo.基础表_角色模块信息 + WHERE id = 135 + AND pid = 163 + AND 角色编号 = 2 +) +BEGIN + INSERT INTO dbo.基础表_角色模块信息 + ( + id, + pid, + 模块顺序, + 角色编号, + 是否启用, + 角色模块顺序 + ) + VALUES + ( + 135, + 163, + 135, + 2, + 1, + 7 + ); +END +ELSE +BEGIN + UPDATE dbo.基础表_角色模块信息 + SET 是否启用 = 1, + 角色模块顺序 = 7 + WHERE id = 135 + AND pid = 163 + AND 角色编号 = 2; +END; + +IF NOT EXISTS +( + SELECT 1 + FROM dbo.基础表_角色模块信息 + WHERE id = 45 + AND pid = 164 + AND 角色编号 = 2 +) +BEGIN + INSERT INTO dbo.基础表_角色模块信息 + ( + id, + pid, + 模块顺序, + 角色编号, + 是否启用, + 角色模块顺序 + ) + VALUES + ( + 45, + 164, + 45, + 2, + 1, + 24 + ); +END +ELSE +BEGIN + UPDATE dbo.基础表_角色模块信息 + SET 是否启用 = 1, + 角色模块顺序 = 24 + WHERE id = 45 + AND pid = 164 + AND 角色编号 = 2; +END; + +DECLARE @OrderMap TABLE +( + id INT PRIMARY KEY, + pid INT NOT NULL, + 顺序 INT NOT NULL +); + +INSERT INTO @OrderMap (id, pid, 顺序) +VALUES +(132, 159, 1), +(67, 160, 1), +(11, 160, 2), +(12, 160, 3), +(13, 160, 4), +(14, 160, 5), +(147, 160, 6), +(68, 160, 7), +(17, 160, 8), +(16, 160, 9), +(18, 160, 10), +(81, 160, 11), +(19, 160, 12), +(15, 160, 13), +(99, 160, 14), +(86, 160, 15), +(87, 160, 16), +(108, 160, 17), +(114, 160, 18), +(120, 160, 19), +(82, 160, 20), +(129, 160, 21), +(155, 160, 22), +(156, 160, 23), +(35, 160, 24), +(36, 160, 25), +(37, 160, 26), +(41, 160, 27), +(124, 160, 28), +(157, 160, 29), +(88, 160, 30), +(94, 161, 1), +(78, 161, 2), +(28, 161, 3), +(98, 161, 4), +(80, 161, 5), +(29, 161, 6), +(79, 161, 7), +(30, 161, 8), +(100, 161, 9), +(84, 161, 10), +(95, 161, 11), +(153, 161, 12), +(154, 161, 13), +(149, 161, 14), +(25, 162, 1), +(69, 162, 2), +(24, 162, 3), +(102, 162, 4), +(21, 162, 5), +(22, 162, 6), +(23, 162, 7), +(117, 162, 8), +(134, 162, 9), +(150, 162, 10), +(125, 162, 11), +(126, 162, 12), +(133, 162, 13), +(104, 163, 1), +(110, 163, 2), +(103, 163, 3), +(121, 163, 4), +(128, 163, 5), +(131, 163, 6), +(135, 163, 7), +(43, 164, 1), +(112, 164, 2), +(44, 164, 3), +(46, 164, 4), +(47, 164, 5), +(48, 164, 6), +(49, 164, 7), +(75, 164, 8), +(51, 164, 9), +(76, 164, 10), +(77, 164, 11), +(50, 164, 12), +(92, 164, 13), +(93, 164, 14), +(96, 164, 15), +(118, 164, 16), +(122, 164, 17), +(123, 164, 18), +(130, 164, 19), +(138, 164, 20), +(143, 164, 21), +(151, 164, 22), +(158, 164, 23), +(45, 164, 24); + +UPDATE r +SET r.pid = o.pid, + r.模块顺序 = r.id, + r.是否启用 = 1, + r.角色模块顺序 = o.顺序 +FROM dbo.基础表_角色模块信息 r +INNER JOIN @OrderMap o ON o.id = r.id +WHERE r.角色编号 = 2 + AND r.pid IN (159, 160, 161, 162, 163, 164); + +SELECT p.title AS 一级菜单, COUNT(*) AS 二级数量 +FROM dbo.基础表_角色模块信息 r +INNER JOIN dbo.基础表_模块信息 p ON p.id = r.pid +WHERE r.角色编号 = 2 + AND ISNULL(r.是否启用, 1) = 1 + AND r.pid IN (159, 160, 161, 162, 163, 164) +GROUP BY p.title, r.pid +ORDER BY r.pid; + +COMMIT TRAN; diff --git a/sql/工序工价_公式调整_正式库_20260808.sql b/sql/工序工价_公式调整_正式库_20260808.sql new file mode 100644 index 00000000..f0c4cbf1 --- /dev/null +++ b/sql/工序工价_公式调整_正式库_20260808.sql @@ -0,0 +1,287 @@ +USE [ERPTOOL_JY] +GO + +SET ANSI_NULLS ON +GO + +SET QUOTED_IDENTIFIER ON +GO + +-- 工序工价编辑保存公式输入 F、G、H,并由触发器统一计算 I、J;修改人:Ld 修改时间:2026-08-08 10:24:44; +ALTER PROCEDURE [dbo].[车间生产管理工艺_工序工价_编辑数据] + @工价流水号 NVARCHAR(50) = N'', + @工艺名称 NVARCHAR(100) = N'', + @工序名称 NVARCHAR(100) = N'', + @零件名称 NVARCHAR(100) = N'', + @图号 NVARCHAR(100) = N'', + @机动时间s NVARCHAR(50) = N'', + @辅助时间s NVARCHAR(50) = N'', + @总时间s NVARCHAR(50) = N'', + @单装数量件 NVARCHAR(50) = N'', + @操作台数 NVARCHAR(50) = N'', + @日产能件 NVARCHAR(50) = N'', + @最终单价元件 NVARCHAR(50) = N'', + @生效日期 NVARCHAR(50) = N'', + @变更次数 NVARCHAR(50) = N'', + @是否启用 NVARCHAR(20) = N'', + @备注 NVARCHAR(500) = N'', + @工序流水号 NVARCHAR(50) = N'', + @修改人 NVARCHAR(50) = N'', + @工作时间时 NVARCHAR(50) = N'', + @宽放时间时 NVARCHAR(50) = N'', + @日工资元 NVARCHAR(50) = N'' +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @Id INT; + DECLARE @Safe工序流水号 INT; + DECLARE @Safe机动时间s DECIMAL(18, 4); + DECLARE @Safe辅助时间s DECIMAL(18, 4); + DECLARE @Safe总时间s DECIMAL(18, 4); + DECLARE @Safe单装数量件 DECIMAL(18, 4); + DECLARE @Safe操作台数 DECIMAL(18, 4); + DECLARE @Safe日产能件 DECIMAL(18, 4); + DECLARE @Safe最终单价元件 DECIMAL(18, 4); + DECLARE @Safe工作时间时 DECIMAL(18, 4); + DECLARE @Safe宽放时间时 DECIMAL(18, 4); + DECLARE @Safe日工资元 DECIMAL(18, 4); + DECLARE @Safe生效日期 DATE; + DECLARE @Safe变更次数 INT; + DECLARE @Safe是否启用 BIT = CASE WHEN NULLIF(@是否启用, N'') IS NULL THEN 1 WHEN @是否启用 = N'1' THEN 1 ELSE 0 END; + DECLARE @操作人 NVARCHAR(50) = NULLIF(@修改人, N''); + DECLARE @当前时间 DATETIME = GETDATE(); + DECLARE @旧数据 NVARCHAR(MAX); + DECLARE @新数据 NVARCHAR(MAX); + DECLARE @Old工序流水号 INT; + + SET @Id = CASE WHEN ISNUMERIC(NULLIF(@工价流水号, N'')) = 1 THEN CONVERT(INT, @工价流水号) ELSE NULL END; + SET @Safe工序流水号 = CASE WHEN ISNUMERIC(NULLIF(@工序流水号, N'')) = 1 THEN CONVERT(INT, @工序流水号) ELSE NULL END; + SET @Safe机动时间s = CASE WHEN ISNUMERIC(NULLIF(@机动时间s, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @机动时间s) ELSE 0 END; + SET @Safe辅助时间s = CASE WHEN ISNUMERIC(NULLIF(@辅助时间s, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @辅助时间s) ELSE 0 END; + -- 修改人:Ld 修改时间:2026-08-08 10:24:44; E 固定按 C+D 计算,不使用前端传入的总时间 + SET @Safe总时间s = @Safe机动时间s + @Safe辅助时间s; + SET @Safe单装数量件 = CASE WHEN ISNUMERIC(NULLIF(@单装数量件, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @单装数量件) ELSE 0 END; + SET @Safe操作台数 = CASE WHEN ISNUMERIC(NULLIF(@操作台数, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @操作台数) ELSE 0 END; + SET @Safe日产能件 = CASE WHEN ISNUMERIC(NULLIF(@日产能件, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @日产能件) ELSE 0 END; + SET @Safe最终单价元件 = CASE WHEN ISNUMERIC(NULLIF(@最终单价元件, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @最终单价元件) ELSE 0 END; + -- 修改人:Ld 修改时间:2026-08-08 10:24:44; 兼容旧接口未传 F、G、H 时,按新公式反推输入字段 + SET @Safe工作时间时 = CASE + WHEN ISNUMERIC(NULLIF(@工作时间时, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @工作时间时) + WHEN @Safe日产能件 <> 0 AND @Safe总时间s <> 0 AND @Safe单装数量件 <> 0 + THEN @Safe日产能件 * @Safe总时间s / (3600 * @Safe单装数量件) + ELSE 0 + END; + SET @Safe宽放时间时 = CASE WHEN ISNUMERIC(NULLIF(@宽放时间时, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @宽放时间时) ELSE 0 END; + SET @Safe日工资元 = CASE + WHEN ISNUMERIC(NULLIF(@日工资元, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @日工资元) + WHEN @Safe最终单价元件 <> 0 AND @Safe日产能件 <> 0 AND @Safe操作台数 <> 0 + THEN @Safe最终单价元件 * @Safe操作台数 * @Safe日产能件 + ELSE 0 + END; + SET @Safe生效日期 = CASE WHEN ISDATE(NULLIF(@生效日期, N'')) = 1 THEN CONVERT(DATE, @生效日期) ELSE NULL END; + SET @Safe变更次数 = CASE WHEN ISNUMERIC(NULLIF(@变更次数, N'')) = 1 THEN CONVERT(INT, @变更次数) ELSE 0 END; + + IF @Safe工序流水号 IS NULL + BEGIN + SELECT N'0' AS result, N'工序流水号不能为空' AS message; + RETURN; + END; + + IF NULLIF(LTRIM(RTRIM(@工艺名称)), N'') IS NULL + OR NULLIF(LTRIM(RTRIM(@工序名称)), N'') IS NULL + OR NULLIF(LTRIM(RTRIM(@零件名称)), N'') IS NULL + OR NULLIF(LTRIM(RTRIM(@图号)), N'') IS NULL + BEGIN + SELECT N'0' AS result, N'工艺名称、工序名称、零件名称和图号不能为空' AS message; + RETURN; + END; + + IF @Id IS NULL + BEGIN + SELECT TOP 1 @Id = 工价流水号 + FROM [dbo].[车间生产管理工艺_工序工价] + WHERE 工序流水号 = @Safe工序流水号; + END; + + IF @Id IS NOT NULL + AND NOT EXISTS ( + SELECT 1 + FROM [dbo].[车间生产管理工艺_工序工价] + WHERE 工价流水号 = @Id + ) + BEGIN + SELECT N'0' AS result, N'工序工价记录不存在' AS message; + RETURN; + END; + + BEGIN TRY + BEGIN TRAN; + + IF @Id IS NOT NULL + BEGIN + SELECT + @Old工序流水号 = 工序流水号, + @旧数据 = [dbo].[车间生产管理工艺_工序工价_历史快照]( + [机动时间s], + [辅助时间s], + [总时间s], + [单装数量(件)], + [操作台数], + [日产能(件)], + [最终单价(元/件)], + 生效日期, + 变更次数 + ) + FROM [dbo].[车间生产管理工艺_工序工价] + WHERE 工价流水号 = @Id; + + UPDATE [dbo].[车间生产管理工艺_工序工价] + SET 工序流水号 = @Safe工序流水号, + 工艺名称 = LTRIM(RTRIM(@工艺名称)), + 工序名称 = LTRIM(RTRIM(@工序名称)), + 零件名称 = LTRIM(RTRIM(@零件名称)), + 图号 = LTRIM(RTRIM(@图号)), + [机动时间s] = @Safe机动时间s, + [辅助时间s] = @Safe辅助时间s, + [总时间s] = @Safe总时间s, + [单装数量(件)] = @Safe单装数量件, + [操作台数] = @Safe操作台数, + [日产能(件)] = @Safe日产能件, + [最终单价(元/件)] = @Safe最终单价元件, + [工作时间(时)] = @Safe工作时间时, + [宽放时间(时)] = @Safe宽放时间时, + [日工资(元)] = @Safe日工资元, + 生效日期 = @Safe生效日期, + 变更次数 = @Safe变更次数, + 是否启用 = @Safe是否启用, + 备注 = NULLIF(@备注, N''), + 计价方式 = N'按件', + 单件工价 = @Safe最终单价元件, + 修改人 = @操作人, + 修改时间 = @当前时间 + WHERE 工价流水号 = @Id; + END + ELSE + BEGIN + INSERT INTO [dbo].[车间生产管理工艺_工序工价]( + 工序流水号, 工艺名称, 工序名称, 零件名称, 图号, + [机动时间s], [辅助时间s], [总时间s], [单装数量(件)], [操作台数], + [日产能(件)], [最终单价(元/件)], [工作时间(时)], [宽放时间(时)], [日工资(元)], + 生效日期, 变更次数, 是否启用, 备注, + 创建人, 创建时间, 修改人, 修改时间, 计价方式, 单件工价 + ) + VALUES ( + @Safe工序流水号, LTRIM(RTRIM(@工艺名称)), LTRIM(RTRIM(@工序名称)), LTRIM(RTRIM(@零件名称)), LTRIM(RTRIM(@图号)), + @Safe机动时间s, @Safe辅助时间s, @Safe总时间s, @Safe单装数量件, @Safe操作台数, + @Safe日产能件, @Safe最终单价元件, @Safe工作时间时, @Safe宽放时间时, @Safe日工资元, + @Safe生效日期, @Safe变更次数, @Safe是否启用, NULLIF(@备注, N''), + @操作人, @当前时间, @操作人, @当前时间, N'按件', @Safe最终单价元件 + ); + + SET @Id = SCOPE_IDENTITY(); + SET @Old工序流水号 = @Safe工序流水号; + SET @旧数据 = N''; + END; + + SET @新数据 = [dbo].[车间生产管理工艺_工序工价_历史快照]( + @Safe机动时间s, @Safe辅助时间s, @Safe总时间s, @Safe单装数量件, @Safe操作台数, + @Safe日产能件, @Safe最终单价元件, @Safe生效日期, @Safe变更次数 + ); + + INSERT INTO [dbo].[车间生产管理工艺_工序工价历史记录]( + 工价流水号, 工序流水号, 工艺名称, 工序名称, 零件名称, 图号, + 操作类型, 变更前, 变更后, 操作人, 操作时间, 备注 + ) + VALUES ( + @Id, ISNULL(@Safe工序流水号, @Old工序流水号), LTRIM(RTRIM(@工艺名称)), LTRIM(RTRIM(@工序名称)), + LTRIM(RTRIM(@零件名称)), LTRIM(RTRIM(@图号)), CASE WHEN @旧数据 = N'' THEN N'新增' ELSE N'编辑' END, + @旧数据, @新数据, @操作人, @当前时间, NULLIF(@备注, N'') + ); + + COMMIT TRAN; + SELECT N'1' AS result, @Id AS 工价流水号; + END TRY + BEGIN CATCH + IF @@TRANCOUNT > 0 + ROLLBACK TRAN; + SELECT N'0' AS result, ERROR_MESSAGE() AS message; + END CATCH; +END +GO + +-- 工序工价字段公式:E=C+D,I=F*3600/E*A,J=H/B/I;修改人:Ld 修改时间:2026-08-08 10:24:44; +IF OBJECT_ID(N'[dbo].[TR_车间生产管理工艺_工序工价_字段公式计算]', N'TR') IS NOT NULL + DROP TRIGGER [dbo].[TR_车间生产管理工艺_工序工价_字段公式计算]; +GO + +CREATE TRIGGER [dbo].[TR_车间生产管理工艺_工序工价_字段公式计算] +ON [dbo].[车间生产管理工艺_工序工价] +AFTER INSERT, UPDATE +AS +BEGIN + SET NOCOUNT ON; + + IF TRIGGER_NESTLEVEL() > 1 + RETURN; + + ;WITH FormulaSource AS ( + SELECT + price.工价流水号, + ISNULL(price.[机动时间s], 0) + ISNULL(price.[辅助时间s], 0) AS 总时间s, + ISNULL(price.[单装数量(件)], 0) AS 单装数量件, + ISNULL(price.[操作台数], 0) AS 操作台数, + -- 修改人:Ld 修改时间:2026-08-08 10:24:44; F 优先保存页面输入,旧接口仅传日产能时按 I=F*3600/E*A 反推 + CASE + WHEN ISNULL(price.[工作时间(时)], 0) <> 0 THEN ISNULL(price.[工作时间(时)], 0) + WHEN ISNULL(price.[日产能(件)], 0) <> 0 + AND ISNULL(price.[机动时间s], 0) + ISNULL(price.[辅助时间s], 0) <> 0 + AND ISNULL(price.[单装数量(件)], 0) <> 0 + THEN ISNULL(price.[日产能(件)], 0) * (ISNULL(price.[机动时间s], 0) + ISNULL(price.[辅助时间s], 0)) / (3600 * ISNULL(price.[单装数量(件)], 0)) + ELSE 0 + END AS 工作时间时, + ISNULL(price.[宽放时间(时)], 0) AS 宽放时间时, + -- 修改人:Ld 修改时间:2026-08-08 10:24:44; H 优先保存页面输入,旧接口仅传工价定额时按 J=H/B/I 反推 + CASE + WHEN ISNULL(price.[日工资(元)], 0) <> 0 THEN ISNULL(price.[日工资(元)], 0) + WHEN ISNULL(price.[最终单价(元/件)], 0) <> 0 + AND ISNULL(price.[日产能(件)], 0) <> 0 + AND ISNULL(price.[操作台数], 0) <> 0 + THEN ISNULL(price.[最终单价(元/件)], 0) * ISNULL(price.[操作台数], 0) * ISNULL(price.[日产能(件)], 0) + ELSE 0 + END AS 日工资元 + FROM [dbo].[车间生产管理工艺_工序工价] price + INNER JOIN inserted i ON price.工价流水号 = i.工价流水号 + ), + FormulaResult AS ( + SELECT + 工价流水号, + 总时间s, + 工作时间时, + 宽放时间时, + 日工资元, + 单装数量件, + 操作台数, + CASE WHEN 总时间s <> 0 THEN 工作时间时 * 3600 / 总时间s * 单装数量件 ELSE 0 END AS 标准产能件天 + FROM FormulaSource + ) + UPDATE price + SET price.[总时间s] = calc.总时间s, + price.[工作时间(时)] = calc.工作时间时, + price.[宽放时间(时)] = calc.宽放时间时, + price.[日工资(元)] = calc.日工资元, + price.[标准产能(件/天)] = calc.标准产能件天, + price.[工价定额] = CASE WHEN calc.操作台数 <> 0 AND calc.标准产能件天 <> 0 THEN calc.日工资元 / calc.操作台数 / calc.标准产能件天 ELSE 0 END, + price.[日产能(件)] = calc.标准产能件天, + price.[最终单价(元/件)] = CASE WHEN calc.操作台数 <> 0 AND calc.标准产能件天 <> 0 THEN calc.日工资元 / calc.操作台数 / calc.标准产能件天 ELSE 0 END, + price.单件工价 = CASE WHEN calc.操作台数 <> 0 AND calc.标准产能件天 <> 0 THEN calc.日工资元 / calc.操作台数 / calc.标准产能件天 ELSE 0 END + FROM [dbo].[车间生产管理工艺_工序工价] price + INNER JOIN FormulaResult calc ON price.工价流水号 = calc.工价流水号; +END +GO + +-- 按新公式回算测试库现有数据;修改人:Ld 修改时间:2026-08-08 10:24:44; +UPDATE [dbo].[车间生产管理工艺_工序工价] +SET [工作时间(时)] = [工作时间(时)]; +GO + diff --git a/sql/工序工价_公式调整_测试库_20260808.sql b/sql/工序工价_公式调整_测试库_20260808.sql new file mode 100644 index 00000000..82c10489 --- /dev/null +++ b/sql/工序工价_公式调整_测试库_20260808.sql @@ -0,0 +1,286 @@ +USE [ERPTOOL_JY_20250826Back] +GO + +SET ANSI_NULLS ON +GO + +SET QUOTED_IDENTIFIER ON +GO + +-- 工序工价编辑保存公式输入 F、G、H,并由触发器统一计算 I、J;修改人:Ld 修改时间:2026-08-08 10:24:44; +ALTER PROCEDURE [dbo].[车间生产管理工艺_工序工价_编辑数据] + @工价流水号 NVARCHAR(50) = N'', + @工艺名称 NVARCHAR(100) = N'', + @工序名称 NVARCHAR(100) = N'', + @零件名称 NVARCHAR(100) = N'', + @图号 NVARCHAR(100) = N'', + @机动时间s NVARCHAR(50) = N'', + @辅助时间s NVARCHAR(50) = N'', + @总时间s NVARCHAR(50) = N'', + @单装数量件 NVARCHAR(50) = N'', + @操作台数 NVARCHAR(50) = N'', + @日产能件 NVARCHAR(50) = N'', + @最终单价元件 NVARCHAR(50) = N'', + @生效日期 NVARCHAR(50) = N'', + @变更次数 NVARCHAR(50) = N'', + @是否启用 NVARCHAR(20) = N'', + @备注 NVARCHAR(500) = N'', + @工序流水号 NVARCHAR(50) = N'', + @修改人 NVARCHAR(50) = N'', + @工作时间时 NVARCHAR(50) = N'', + @宽放时间时 NVARCHAR(50) = N'', + @日工资元 NVARCHAR(50) = N'' +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @Id INT; + DECLARE @Safe工序流水号 INT; + DECLARE @Safe机动时间s DECIMAL(18, 4); + DECLARE @Safe辅助时间s DECIMAL(18, 4); + DECLARE @Safe总时间s DECIMAL(18, 4); + DECLARE @Safe单装数量件 DECIMAL(18, 4); + DECLARE @Safe操作台数 DECIMAL(18, 4); + DECLARE @Safe日产能件 DECIMAL(18, 4); + DECLARE @Safe最终单价元件 DECIMAL(18, 4); + DECLARE @Safe工作时间时 DECIMAL(18, 4); + DECLARE @Safe宽放时间时 DECIMAL(18, 4); + DECLARE @Safe日工资元 DECIMAL(18, 4); + DECLARE @Safe生效日期 DATE; + DECLARE @Safe变更次数 INT; + DECLARE @Safe是否启用 BIT = CASE WHEN NULLIF(@是否启用, N'') IS NULL THEN 1 WHEN @是否启用 = N'1' THEN 1 ELSE 0 END; + DECLARE @操作人 NVARCHAR(50) = NULLIF(@修改人, N''); + DECLARE @当前时间 DATETIME = GETDATE(); + DECLARE @旧数据 NVARCHAR(MAX); + DECLARE @新数据 NVARCHAR(MAX); + DECLARE @Old工序流水号 INT; + + SET @Id = CASE WHEN ISNUMERIC(NULLIF(@工价流水号, N'')) = 1 THEN CONVERT(INT, @工价流水号) ELSE NULL END; + SET @Safe工序流水号 = CASE WHEN ISNUMERIC(NULLIF(@工序流水号, N'')) = 1 THEN CONVERT(INT, @工序流水号) ELSE NULL END; + SET @Safe机动时间s = CASE WHEN ISNUMERIC(NULLIF(@机动时间s, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @机动时间s) ELSE 0 END; + SET @Safe辅助时间s = CASE WHEN ISNUMERIC(NULLIF(@辅助时间s, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @辅助时间s) ELSE 0 END; + -- 修改人:Ld 修改时间:2026-08-08 10:24:44; E 固定按 C+D 计算,不使用前端传入的总时间 + SET @Safe总时间s = @Safe机动时间s + @Safe辅助时间s; + SET @Safe单装数量件 = CASE WHEN ISNUMERIC(NULLIF(@单装数量件, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @单装数量件) ELSE 0 END; + SET @Safe操作台数 = CASE WHEN ISNUMERIC(NULLIF(@操作台数, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @操作台数) ELSE 0 END; + SET @Safe日产能件 = CASE WHEN ISNUMERIC(NULLIF(@日产能件, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @日产能件) ELSE 0 END; + SET @Safe最终单价元件 = CASE WHEN ISNUMERIC(NULLIF(@最终单价元件, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @最终单价元件) ELSE 0 END; + -- 修改人:Ld 修改时间:2026-08-08 10:24:44; 兼容旧接口未传 F、G、H 时,按新公式反推输入字段 + SET @Safe工作时间时 = CASE + WHEN ISNUMERIC(NULLIF(@工作时间时, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @工作时间时) + WHEN @Safe日产能件 <> 0 AND @Safe总时间s <> 0 AND @Safe单装数量件 <> 0 + THEN @Safe日产能件 * @Safe总时间s / (3600 * @Safe单装数量件) + ELSE 0 + END; + SET @Safe宽放时间时 = CASE WHEN ISNUMERIC(NULLIF(@宽放时间时, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @宽放时间时) ELSE 0 END; + SET @Safe日工资元 = CASE + WHEN ISNUMERIC(NULLIF(@日工资元, N'')) = 1 THEN CONVERT(DECIMAL(18, 4), @日工资元) + WHEN @Safe最终单价元件 <> 0 AND @Safe日产能件 <> 0 AND @Safe操作台数 <> 0 + THEN @Safe最终单价元件 * @Safe操作台数 * @Safe日产能件 + ELSE 0 + END; + SET @Safe生效日期 = CASE WHEN ISDATE(NULLIF(@生效日期, N'')) = 1 THEN CONVERT(DATE, @生效日期) ELSE NULL END; + SET @Safe变更次数 = CASE WHEN ISNUMERIC(NULLIF(@变更次数, N'')) = 1 THEN CONVERT(INT, @变更次数) ELSE 0 END; + + IF @Safe工序流水号 IS NULL + BEGIN + SELECT N'0' AS result, N'工序流水号不能为空' AS message; + RETURN; + END; + + IF NULLIF(LTRIM(RTRIM(@工艺名称)), N'') IS NULL + OR NULLIF(LTRIM(RTRIM(@工序名称)), N'') IS NULL + OR NULLIF(LTRIM(RTRIM(@零件名称)), N'') IS NULL + OR NULLIF(LTRIM(RTRIM(@图号)), N'') IS NULL + BEGIN + SELECT N'0' AS result, N'工艺名称、工序名称、零件名称和图号不能为空' AS message; + RETURN; + END; + + IF @Id IS NULL + BEGIN + SELECT TOP 1 @Id = 工价流水号 + FROM [dbo].[车间生产管理工艺_工序工价] + WHERE 工序流水号 = @Safe工序流水号; + END; + + IF @Id IS NOT NULL + AND NOT EXISTS ( + SELECT 1 + FROM [dbo].[车间生产管理工艺_工序工价] + WHERE 工价流水号 = @Id + ) + BEGIN + SELECT N'0' AS result, N'工序工价记录不存在' AS message; + RETURN; + END; + + BEGIN TRY + BEGIN TRAN; + + IF @Id IS NOT NULL + BEGIN + SELECT + @Old工序流水号 = 工序流水号, + @旧数据 = [dbo].[车间生产管理工艺_工序工价_历史快照]( + [机动时间s], + [辅助时间s], + [总时间s], + [单装数量(件)], + [操作台数], + [日产能(件)], + [最终单价(元/件)], + 生效日期, + 变更次数 + ) + FROM [dbo].[车间生产管理工艺_工序工价] + WHERE 工价流水号 = @Id; + + UPDATE [dbo].[车间生产管理工艺_工序工价] + SET 工序流水号 = @Safe工序流水号, + 工艺名称 = LTRIM(RTRIM(@工艺名称)), + 工序名称 = LTRIM(RTRIM(@工序名称)), + 零件名称 = LTRIM(RTRIM(@零件名称)), + 图号 = LTRIM(RTRIM(@图号)), + [机动时间s] = @Safe机动时间s, + [辅助时间s] = @Safe辅助时间s, + [总时间s] = @Safe总时间s, + [单装数量(件)] = @Safe单装数量件, + [操作台数] = @Safe操作台数, + [日产能(件)] = @Safe日产能件, + [最终单价(元/件)] = @Safe最终单价元件, + [工作时间(时)] = @Safe工作时间时, + [宽放时间(时)] = @Safe宽放时间时, + [日工资(元)] = @Safe日工资元, + 生效日期 = @Safe生效日期, + 变更次数 = @Safe变更次数, + 是否启用 = @Safe是否启用, + 备注 = NULLIF(@备注, N''), + 计价方式 = N'按件', + 单件工价 = @Safe最终单价元件, + 修改人 = @操作人, + 修改时间 = @当前时间 + WHERE 工价流水号 = @Id; + END + ELSE + BEGIN + INSERT INTO [dbo].[车间生产管理工艺_工序工价]( + 工序流水号, 工艺名称, 工序名称, 零件名称, 图号, + [机动时间s], [辅助时间s], [总时间s], [单装数量(件)], [操作台数], + [日产能(件)], [最终单价(元/件)], [工作时间(时)], [宽放时间(时)], [日工资(元)], + 生效日期, 变更次数, 是否启用, 备注, + 创建人, 创建时间, 修改人, 修改时间, 计价方式, 单件工价 + ) + VALUES ( + @Safe工序流水号, LTRIM(RTRIM(@工艺名称)), LTRIM(RTRIM(@工序名称)), LTRIM(RTRIM(@零件名称)), LTRIM(RTRIM(@图号)), + @Safe机动时间s, @Safe辅助时间s, @Safe总时间s, @Safe单装数量件, @Safe操作台数, + @Safe日产能件, @Safe最终单价元件, @Safe工作时间时, @Safe宽放时间时, @Safe日工资元, + @Safe生效日期, @Safe变更次数, @Safe是否启用, NULLIF(@备注, N''), + @操作人, @当前时间, @操作人, @当前时间, N'按件', @Safe最终单价元件 + ); + + SET @Id = SCOPE_IDENTITY(); + SET @Old工序流水号 = @Safe工序流水号; + SET @旧数据 = N''; + END; + + SET @新数据 = [dbo].[车间生产管理工艺_工序工价_历史快照]( + @Safe机动时间s, @Safe辅助时间s, @Safe总时间s, @Safe单装数量件, @Safe操作台数, + @Safe日产能件, @Safe最终单价元件, @Safe生效日期, @Safe变更次数 + ); + + INSERT INTO [dbo].[车间生产管理工艺_工序工价历史记录]( + 工价流水号, 工序流水号, 工艺名称, 工序名称, 零件名称, 图号, + 操作类型, 变更前, 变更后, 操作人, 操作时间, 备注 + ) + VALUES ( + @Id, ISNULL(@Safe工序流水号, @Old工序流水号), LTRIM(RTRIM(@工艺名称)), LTRIM(RTRIM(@工序名称)), + LTRIM(RTRIM(@零件名称)), LTRIM(RTRIM(@图号)), CASE WHEN @旧数据 = N'' THEN N'新增' ELSE N'编辑' END, + @旧数据, @新数据, @操作人, @当前时间, NULLIF(@备注, N'') + ); + + COMMIT TRAN; + SELECT N'1' AS result, @Id AS 工价流水号; + END TRY + BEGIN CATCH + IF @@TRANCOUNT > 0 + ROLLBACK TRAN; + SELECT N'0' AS result, ERROR_MESSAGE() AS message; + END CATCH; +END +GO + +-- 工序工价字段公式:E=C+D,I=F*3600/E*A,J=H/B/I;修改人:Ld 修改时间:2026-08-08 10:24:44; +IF OBJECT_ID(N'[dbo].[TR_车间生产管理工艺_工序工价_字段公式计算]', N'TR') IS NOT NULL + DROP TRIGGER [dbo].[TR_车间生产管理工艺_工序工价_字段公式计算]; +GO + +CREATE TRIGGER [dbo].[TR_车间生产管理工艺_工序工价_字段公式计算] +ON [dbo].[车间生产管理工艺_工序工价] +AFTER INSERT, UPDATE +AS +BEGIN + SET NOCOUNT ON; + + IF TRIGGER_NESTLEVEL() > 1 + RETURN; + + ;WITH FormulaSource AS ( + SELECT + price.工价流水号, + ISNULL(price.[机动时间s], 0) + ISNULL(price.[辅助时间s], 0) AS 总时间s, + ISNULL(price.[单装数量(件)], 0) AS 单装数量件, + ISNULL(price.[操作台数], 0) AS 操作台数, + -- 修改人:Ld 修改时间:2026-08-08 10:24:44; F 优先保存页面输入,旧接口仅传日产能时按 I=F*3600/E*A 反推 + CASE + WHEN ISNULL(price.[工作时间(时)], 0) <> 0 THEN ISNULL(price.[工作时间(时)], 0) + WHEN ISNULL(price.[日产能(件)], 0) <> 0 + AND ISNULL(price.[机动时间s], 0) + ISNULL(price.[辅助时间s], 0) <> 0 + AND ISNULL(price.[单装数量(件)], 0) <> 0 + THEN ISNULL(price.[日产能(件)], 0) * (ISNULL(price.[机动时间s], 0) + ISNULL(price.[辅助时间s], 0)) / (3600 * ISNULL(price.[单装数量(件)], 0)) + ELSE 0 + END AS 工作时间时, + ISNULL(price.[宽放时间(时)], 0) AS 宽放时间时, + -- 修改人:Ld 修改时间:2026-08-08 10:24:44; H 优先保存页面输入,旧接口仅传工价定额时按 J=H/B/I 反推 + CASE + WHEN ISNULL(price.[日工资(元)], 0) <> 0 THEN ISNULL(price.[日工资(元)], 0) + WHEN ISNULL(price.[最终单价(元/件)], 0) <> 0 + AND ISNULL(price.[日产能(件)], 0) <> 0 + AND ISNULL(price.[操作台数], 0) <> 0 + THEN ISNULL(price.[最终单价(元/件)], 0) * ISNULL(price.[操作台数], 0) * ISNULL(price.[日产能(件)], 0) + ELSE 0 + END AS 日工资元 + FROM [dbo].[车间生产管理工艺_工序工价] price + INNER JOIN inserted i ON price.工价流水号 = i.工价流水号 + ), + FormulaResult AS ( + SELECT + 工价流水号, + 总时间s, + 工作时间时, + 宽放时间时, + 日工资元, + 单装数量件, + 操作台数, + CASE WHEN 总时间s <> 0 THEN 工作时间时 * 3600 / 总时间s * 单装数量件 ELSE 0 END AS 标准产能件天 + FROM FormulaSource + ) + UPDATE price + SET price.[总时间s] = calc.总时间s, + price.[工作时间(时)] = calc.工作时间时, + price.[宽放时间(时)] = calc.宽放时间时, + price.[日工资(元)] = calc.日工资元, + price.[标准产能(件/天)] = calc.标准产能件天, + price.[工价定额] = CASE WHEN calc.操作台数 <> 0 AND calc.标准产能件天 <> 0 THEN calc.日工资元 / calc.操作台数 / calc.标准产能件天 ELSE 0 END, + price.[日产能(件)] = calc.标准产能件天, + price.[最终单价(元/件)] = CASE WHEN calc.操作台数 <> 0 AND calc.标准产能件天 <> 0 THEN calc.日工资元 / calc.操作台数 / calc.标准产能件天 ELSE 0 END, + price.单件工价 = CASE WHEN calc.操作台数 <> 0 AND calc.标准产能件天 <> 0 THEN calc.日工资元 / calc.操作台数 / calc.标准产能件天 ELSE 0 END + FROM [dbo].[车间生产管理工艺_工序工价] price + INNER JOIN FormulaResult calc ON price.工价流水号 = calc.工价流水号; +END +GO + +-- 按新公式回算测试库现有数据;修改人:Ld 修改时间:2026-08-08 10:24:44; +UPDATE [dbo].[车间生产管理工艺_工序工价] +SET [工作时间(时)] = [工作时间(时)]; +GO diff --git a/sql/装配与工艺菜单迁移_测试库_20260806.sql b/sql/装配与工艺菜单迁移_测试库_20260806.sql new file mode 100644 index 00000000..032f4245 --- /dev/null +++ b/sql/装配与工艺菜单迁移_测试库_20260806.sql @@ -0,0 +1,56 @@ +/* 修改人:Ld 修改时间:2026-08-06 16:23:41; 将工艺查询、工艺管理迁到APS,并将通用件装配、专机装配下二级菜单迁到MES */ +SET XACT_ABORT ON; +BEGIN TRAN; + +DECLARE @MoveMap TABLE +( + id INT PRIMARY KEY, + 目标pid INT NOT NULL, + 顺序 INT NOT NULL +); + +INSERT INTO @MoveMap (id, 目标pid, 顺序) +VALUES +(84, 159, 2), +(95, 159, 3), +(94, 161, 1), +(78, 161, 2), +(28, 161, 3), +(98, 161, 4), +(80, 161, 5), +(29, 161, 6), +(79, 161, 7), +(30, 161, 8), +(100, 161, 9), +(153, 161, 10), +(154, 161, 11), +(149, 161, 12), +(64, 161, 13), +(65, 161, 14), +(66, 161, 15), +(70, 161, 16), +(89, 161, 17), +(90, 161, 18), +(91, 161, 19), +(101, 161, 20), +(72, 161, 21), +(73, 161, 22), +(74, 161, 23); + +UPDATE r +SET r.pid = m.目标pid, + r.模块顺序 = r.id, + r.是否启用 = 1, + r.角色模块顺序 = m.顺序 +FROM dbo.基础表_角色模块信息 r +INNER JOIN @MoveMap m ON m.id = r.id +WHERE r.角色编号 = 2; + +SELECT p.title AS 一级菜单, c.id AS 二级ID, c.title AS 二级菜单, r.角色模块顺序 +FROM @MoveMap m +INNER JOIN dbo.基础表_角色模块信息 r ON r.id = m.id AND r.角色编号 = 2 +INNER JOIN dbo.基础表_模块信息 c ON c.id = r.id +INNER JOIN dbo.基础表_模块信息 p ON p.id = r.pid +ORDER BY p.id, r.角色模块顺序, c.id; + +COMMIT TRAN; diff --git a/sql/车间生产管理工艺_零件工序_派工_空数量校验_正式库_20260805.sql b/sql/车间生产管理工艺_零件工序_派工_空数量校验_正式库_20260805.sql new file mode 100644 index 00000000..05487738 --- /dev/null +++ b/sql/车间生产管理工艺_零件工序_派工_空数量校验_正式库_20260805.sql @@ -0,0 +1,83 @@ +ALTER PROCEDURE [dbo].[车间生产管理工艺_零件工序_派工] + +@工序流水号 int = null, + +@数量 int = null, + +@人员编号 int = null, + +@设备流水号 int = null, + +@调拨员编号 int = null, + +@计划完成日期 nvarchar(50)=null, + +@计划开始日期 nvarchar(50)=null + +AS + +declare @工序顺序 int +declare @工艺计划流水号 int +declare @工艺任务流水号 int +declare @分配日期 nvarchar(50) +declare @剩余料数 int +declare @已领数量 int=0 + +-- 修改人:Ld 修改时间:2026-08-05 09:35:00; 后端兜底校验派工数量,避免空值或非正数落入任务分配表。 +if @数量 is null or @数量 <= 0 +begin + RAISERROR(N'派工数量不能为空且必须大于0', 16, 1) + return +end + +update 车间生产管理工艺_零件工序 set 已分配数 = ISNULL(已分配数,0) + @数量 where 工序流水号=@工序流水号 + +select @工艺计划流水号=工艺计划流水号,@工序顺序=工序顺序,@剩余料数=ISNULL(剩余料数,0) from 车间生产管理工艺_零件工序 where 工序流水号=@工序流水号 + +select @分配日期 = 分配日期 from 车间生产管理工艺_零件工艺计划 where 工艺计划流水号=@工艺计划流水号 + +if @分配日期 is null +begin + update 车间生产管理工艺_零件工艺计划 set 分配日期 = getdate() where 工艺计划流水号=@工艺计划流水号 +end + +if @人员编号 = 16 + begin + update 车间生产管理工艺_零件工序 set 工序间是否外协 = 1,外协数量=@数量 where 工序流水号=@工序流水号 + end + else + begin + update 车间生产管理工艺_零件工序 set 工序间是否外协 = 0,外协数量=0 where 工序流水号=@工序流水号 + end + +if @工序顺序 = 1 +begin + if @数量 > @剩余料数 and @剩余料数 > 0 + begin + set @已领数量 = @剩余料数 + update 车间生产管理工艺_零件工序 set 剩余料数=0 where 工序流水号=@工序流水号 + end + else if @数量 <= @剩余料数 and @剩余料数 > 0 + begin + set @已领数量 = @数量 + update 车间生产管理工艺_零件工序 set 剩余料数=isnull(剩余料数,0)-@数量 where 工序流水号=@工序流水号 + end +end + +if (select COUNT(*) from 车间生产管理工艺_零件工序_任务分配 where 工序流水号=@工序流水号 and 人员编号=@人员编号 and 设备流水号=@设备流水号) = 1 +begin + -- 修改人:Ld 修改时间:2026-08-05 09:35:00; 累加时对历史空值做默认值处理,避免 NULL + 新数量 仍然为 NULL。 + update 车间生产管理工艺_零件工序_任务分配 set 数量=ISNULL(数量,0)+@数量,分配时间=GETDATE(),已领数量=isnull(已领数量,0)+@已领数量,调拨员编号=@调拨员编号,计划完成日期=@计划完成日期,计划开始日期=@计划开始日期 where 工序流水号=@工序流水号 and 人员编号=@人员编号 and 设备流水号=@设备流水号 +end +else +begin +insert into 车间生产管理工艺_零件工序_任务分配(工序流水号,数量,人员编号,设备流水号,分配时间,已领数量,调拨员编号,计划完成日期,计划开始日期)values(@工序流水号,@数量,@人员编号,@设备流水号,GETDATE(),@已领数量,@调拨员编号,@计划完成日期,@计划开始日期) + +if @人员编号 <> 16 +begin +select @工艺任务流水号 = IDENT_CURRENT('车间生产管理工艺_零件工序_任务分配') + +exec 车间生产管理工艺_零件工序_派工_生产计划_增加 @工艺任务流水号,@数量,@计划完成日期,@计划开始日期 + +end +end diff --git a/sql/边界二级组件迁移_测试库_20260806.sql b/sql/边界二级组件迁移_测试库_20260806.sql new file mode 100644 index 00000000..a7a7fbaa --- /dev/null +++ b/sql/边界二级组件迁移_测试库_20260806.sql @@ -0,0 +1,36 @@ +/* 修改人:Ld 修改时间:2026-08-06 16:15:15; 按确认归属补迁订单投产、物料采购进度和新产品合同类二级组件 */ +SET XACT_ABORT ON; +BEGIN TRAN; + +DECLARE @MoveMap TABLE +( + id INT PRIMARY KEY, + 目标pid INT NOT NULL, + 顺序 INT NOT NULL +); + +INSERT INTO @MoveMap (id, 目标pid, 顺序) +VALUES +(88, 160, 31), +(149, 161, 15), +(125, 162, 12), +(126, 162, 13), +(133, 162, 14); + +UPDATE r +SET r.pid = m.目标pid, + r.模块顺序 = r.id, + r.是否启用 = 1, + r.角色模块顺序 = m.顺序 +FROM dbo.基础表_角色模块信息 r +INNER JOIN @MoveMap m ON m.id = r.id +WHERE r.角色编号 = 2; + +SELECT p.title AS 新一级菜单, c.id AS 二级ID, c.title AS 二级菜单, r.角色模块顺序 +FROM @MoveMap m +INNER JOIN dbo.基础表_角色模块信息 r ON r.id = m.id AND r.角色编号 = 2 +INNER JOIN dbo.基础表_模块信息 c ON c.id = r.id +INNER JOIN dbo.基础表_模块信息 p ON p.id = r.pid +ORDER BY p.id, r.角色模块顺序, c.id; + +COMMIT TRAN; diff --git a/src/views/SeikoWorkshop/ProcessPrice/index.vue b/src/views/SeikoWorkshop/ProcessPrice/index.vue index 94545cb4..60afb530 100644 --- a/src/views/SeikoWorkshop/ProcessPrice/index.vue +++ b/src/views/SeikoWorkshop/ProcessPrice/index.vue @@ -215,12 +215,14 @@ - + + - + + @@ -499,7 +501,7 @@ export default { this.form.总时间s = this.getTotalTime(this.form) this.refreshPriceFormula() }, - // 修改人:Ld 修改时间:2026-08-04 09:39:18; 按截图公式计算标准产能和工价定额,并同步旧字段兼容后端编辑过程 + // 修改人:Ld 修改时间:2026-08-08 10:24:44; 按截图公式 I=F*3600/E*A、J=H/B/I 计算,并同步旧字段兼容后端编辑过程 refreshPriceFormula() { if (!this.form) { return @@ -507,8 +509,10 @@ export default { var totalTime = Number(this.form.总时间s || 0) var workTime = Number(this.form['工作时间(时)'] || 0) var dayWage = Number(this.form['日工资(元)'] || 0) - var capacity = totalTime === 0 ? 0 : workTime * 3600 / totalTime - var priceQuota = capacity === 0 ? 0 : dayWage / capacity + var loadingQuantity = Number(this.form['单装数量(件)'] || 0) + var operationCount = Number(this.form.操作台数 || 0) + var capacity = totalTime === 0 ? 0 : workTime * 3600 / totalTime * loadingQuantity + var priceQuota = capacity === 0 || operationCount === 0 ? 0 : dayWage / operationCount / capacity this.form['标准产能(件/天)'] = Number(capacity.toFixed(4)) this.form.工价定额 = Number(priceQuota.toFixed(4)) this.form['日产能(件)'] = this.form['标准产能(件/天)'] @@ -872,6 +876,10 @@ export default { param[15] = ['备注', this.form.备注] param[16] = ['工序流水号', this.form.工序流水号] param[17] = ['修改人', this.id] + // 修改人:Ld 修改时间:2026-08-08 10:24:44; 保存截图公式的 F、G、H 输入值,后端按新公式统一计算 I、J + param[18] = ['工作时间时', this.form['工作时间(时)']] + param[19] = ['宽放时间时', this.form['宽放时间(时)']] + param[20] = ['日工资元', this.form['日工资(元)']] var Data = this.CreateData('12', '车间生产管理工艺_工序工价_编辑数据', param) this.ExecDatabase(Data).then(response => { if (response.data && response.data[0] && response.data[0].result === '1') { diff --git a/src/views/SeikoWorkshop/ProductionPlan/index.vue b/src/views/SeikoWorkshop/ProductionPlan/index.vue index 2d51f5f1..df678ebc 100644 --- a/src/views/SeikoWorkshop/ProductionPlan/index.vue +++ b/src/views/SeikoWorkshop/ProductionPlan/index.vue @@ -232,22 +232,6 @@
-
- 时间筛选 - - 重置 - 按任务派工与完工时间区间筛选 -
暂无后续已派工任务
@@ -341,7 +325,6 @@ export default { machineTaskLoading: false, machineTaskTitle: '机床后续已派工任务', machineTaskData: [], - machineTaskDateRange: [], // 修改人:Ld 修改时间:2026-08-04 09:16:54; APS排产弹窗的固定轴尺寸,保持展示稳定。 machineApsDayWidth: 88, machineApsPersonWidth: 118, @@ -503,27 +486,19 @@ export default { } }) }, - // 修改人:Ld 修改时间:2026-08-04 14:30:24; 弹窗时间筛选后的任务集合,按派工时间与完工期限区间过滤。 + // 修改人:Ld 修改时间:2026-08-05 13:24:30; 方案三弹窗只显示今天及之后的任务,之前的任务不再展示。 machineTaskDisplayData() { - if (!this.machineTaskDateRange || this.machineTaskDateRange.length !== 2) { - return this.machineTaskData - } - var startDate = this.parseApsDate(this.machineTaskDateRange[0]) - var endDate = this.parseApsDate(this.machineTaskDateRange[1]) - if (!startDate || !endDate) { - return this.machineTaskData - } - if (endDate.getTime() < startDate.getTime()) { - var tempDate = startDate - startDate = endDate - endDate = tempDate - } + var today = this.clearApsDate(new Date()) return this.machineTaskData.filter(row => { var rowStart = this.parseApsDate(row.分配时间) || this.parseApsDate(row.精工期限) var rowEnd = this.parseApsDate(row.精工期限) || rowStart if (!rowStart) return false if (!rowEnd) rowEnd = rowStart - return rowStart.getTime() <= endDate.getTime() && rowEnd.getTime() >= startDate.getTime() + return this.clearApsDate(rowEnd).getTime() >= today.getTime() + }).sort((a, b) => { + var aDate = this.parseApsDate(a.分配时间) || this.parseApsDate(a.精工期限) || today + var bDate = this.parseApsDate(b.分配时间) || this.parseApsDate(b.精工期限) || today + return this.clearApsDate(aDate).getTime() - this.clearApsDate(bDate).getTime() }) } }, @@ -607,6 +582,8 @@ export default { _completedProcesses: 0, // 修改人:Ld 修改时间:2026-08-04 08:56:51; 记录每个OP工序是否完成,用于单元格标绿。 _completedOpMap: {}, + // 修改人:Ld 修改时间:2026-08-05 10:18:41; 记录正在生产中的OP工序,用于单元格标黄。 + _producingOpMap: {}, ...this.initializeProcessFields() } }, @@ -644,6 +621,9 @@ export default { if (row._completedOpMap && row._completedOpMap[opKey]) { return 'op-process-completed' } + if (row._producingOpMap && row._producingOpMap[opKey]) { + return 'op-process-producing' + } return '' }, // 修改人:Ld 修改时间:2026-08-04 14:57:36; 合同编号优先取方案一真实关联合同号,没有时保留原提取关联值。 @@ -679,7 +659,6 @@ export default { this.machineTaskData = [] this.machineTaskVisible = true this.machineTaskLoading = true - this.machineTaskDateRange = [] var Data = this.CreateData('11', '精工车间_工况_分页查询', param) this.ExecDatabase(Data).then(response => { if (response.data && response.data.result) { @@ -703,14 +682,6 @@ export default { } return value }, - // 修改人:Ld 修改时间:2026-08-04 14:30:24; 切换弹窗时间范围后刷新APS排产展示。 - changeMachineTaskDateRange() { - this.$forceUpdate() - }, - resetMachineTaskDateRange() { - this.machineTaskDateRange = [] - this.$forceUpdate() - }, // 修改人:Ld 修改时间:2026-08-04 09:16:54; APS排产视图日期解析,兼容后端日期字符串。 parseApsDate(value) { if (!value) return null @@ -763,9 +734,22 @@ export default { } else { group.状态 = '生产中' } + this.markProducingProcess(group) delete group._totalProcesses delete group._completedProcesses }, + // 修改人:Ld 修改时间:2026-08-05 10:18:41; 生产中订单将第一个未完成OP工序标记为正在生产。 + markProducingProcess(group) { + group._producingOpMap = {} + if (group.状态 !== '生产中') return + for (let i = 1; i <= this.processConfig.maxProcessCount; i++) { + var opKey = this.processConfig.processNamePattern.replace('{index}', i) + if (group[opKey] && !(group._completedOpMap && group._completedOpMap[opKey])) { + group._producingOpMap[opKey] = true + return + } + } + }, // 数据分组主逻辑 groupDataByOrder(data) { const grouped = {} @@ -803,7 +787,7 @@ export default { this.filteredTableData.forEach((row, index) => { data.push(this.buildProductionPlanExportRow(row, index)) }) - var ws = XLSX.utils.aoa_to_sheet(data) + var ws = this.getProductionPlanSheetFromArray(data) var range = XLSX.utils.decode_range(ws['!ref']) ws['!merges'] = [{ s: { r: 0, c: 0 }, e: { r: 0, c: headers.length - 1 }}] ws['!cols'] = this.getProductionPlanExportCols() @@ -819,17 +803,56 @@ export default { var opKey = headers[colIndex] if (exportRow && exportRow._completedOpMap && exportRow._completedOpMap[opKey]) { ws[cellAddress].s = this.getProductionPlanCompletedOpExportStyle() + } else if (exportRow && exportRow._producingOpMap && exportRow._producingOpMap[opKey]) { + ws[cellAddress].s = this.getProductionPlanProducingOpExportStyle() } } } } ws['!autofilter'] = { ref: XLSX.utils.encode_range({ s: { r: 1, c: 0 }, e: { r: Math.max(1, range.e.r), c: headers.length - 1 }}) } - var wb = XLSX.utils.book_new() - XLSX.utils.book_append_sheet(wb, ws, this.getProductionPlanExportSheetName()) - var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: false, type: 'array' }) - FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), this.getProductionPlanExportFileName()) + var sheetName = this.getProductionPlanExportSheetName() + var wb = { SheetNames: [sheetName], Sheets: {}, Props: {}} + wb.Sheets[sheetName] = ws + var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: false, type: 'binary' }) + FileSaver.saveAs(new Blob([this.productionPlanStringToArrayBuffer(wbout)], { type: 'application/octet-stream' }), this.getProductionPlanExportFileName()) this.$message.success('导出成功') }, + // 修改人:Ld 修改时间:2026-08-05 08:13:25; 兼容项目当前 xlsx-style 版本,手动将二维数组转换为 worksheet。 + getProductionPlanSheetFromArray(data) { + var ws = {} + var range = { s: { c: 10000000, r: 10000000 }, e: { c: 0, r: 0 }} + for (let rowIndex = 0; rowIndex < data.length; rowIndex++) { + for (let colIndex = 0; colIndex < data[rowIndex].length; colIndex++) { + if (range.s.r > rowIndex) range.s.r = rowIndex + if (range.s.c > colIndex) range.s.c = colIndex + if (range.e.r < rowIndex) range.e.r = rowIndex + if (range.e.c < colIndex) range.e.c = colIndex + var value = data[rowIndex][colIndex] + if (value === null || value === undefined) continue + var cell = { v: value } + if (typeof value === 'number') { + cell.t = 'n' + } else if (typeof value === 'boolean') { + cell.t = 'b' + } else { + cell.t = 's' + } + ws[XLSX.utils.encode_cell({ r: rowIndex, c: colIndex })] = cell + } + } + if (range.s.c < 10000000) { + ws['!ref'] = XLSX.utils.encode_range(range) + } + return ws + }, + productionPlanStringToArrayBuffer(value) { + var buffer = new ArrayBuffer(value.length) + var view = new Uint8Array(buffer) + for (let i = 0; i < value.length; i++) { + view[i] = value.charCodeAt(i) & 0xFF + } + return buffer + }, getProductionPlanExportHeaders() { return ['序号', '状态', '合同编号', '订单编号', '收货人', '投产日期', '订单交货日期', '数量', '总工序', '实际 工序', '产品名称', '零件名称', '零件图号', '材料', '完成率', '当前状态或设备', 'OP010', 'OP020', 'OP030', 'OP040', 'OP050', 'OP060', 'OP070', 'OP080', 'OP090', 'OP100', 'OP110'] }, @@ -935,7 +958,7 @@ export default { } if (rowIndex === 1) { baseStyle.font.bold = false - baseStyle.fill = { fgColor: { rgb: 'FFFFFF' }} + baseStyle.fill = { patternType: 'solid', fgColor: { rgb: 'FFFFFF' }} return baseStyle } if (colIndex === 11 || colIndex === 12) { @@ -958,9 +981,24 @@ export default { return baseStyle }, getProductionPlanCompletedOpExportStyle() { + // 修改人:Ld 修改时间:2026-08-05 08:13:25; xlsx-style 导出填充色指定 solid,保证已完成工序绿色显示。 return { font: { name: '微软雅黑', sz: 10, bold: false, color: { rgb: 'FFFFFF' }}, - fill: { fgColor: { rgb: '67C23A' }}, + fill: { patternType: 'solid', fgColor: { rgb: '67C23A' }}, + alignment: { horizontal: 'center', vertical: 'center', wrapText: true }, + border: { + top: { style: 'thin', color: { rgb: '000000' }}, + bottom: { style: 'thin', color: { rgb: '000000' }}, + left: { style: 'thin', color: { rgb: '000000' }}, + right: { style: 'thin', color: { rgb: '000000' }} + } + } + }, + // 修改人:Ld 修改时间:2026-08-05 10:18:41; xlsx-style 导出填充色指定 solid,保证正在生产工序黄色显示。 + getProductionPlanProducingOpExportStyle() { + return { + font: { name: '微软雅黑', sz: 10, bold: true, color: { rgb: '000000' }}, + fill: { patternType: 'solid', fgColor: { rgb: 'FFC000' }}, alignment: { horizontal: 'center', vertical: 'center', wrapText: true }, border: { top: { style: 'thin', color: { rgb: '000000' }}, @@ -1278,6 +1316,17 @@ export default { border-radius: 2px; } + /* 修改人:Ld 修改时间:2026-08-05 10:18:41; 生产中OP工序标黄,不改变原表格布局。*/ + .op-process-producing { + display: inline-block; + width: 100%; + min-height: 20px; + line-height: 20px; + color: #303133; + background-color: #FFC000; + border-radius: 2px; + } + /* 修改人:Ld 修改时间:2026-08-04 09:07:29; 保持当前状态列宽不变,仅增加机床可点击提示。 */ .machine-task-link { width: 100%; @@ -1294,27 +1343,6 @@ export default { background: #fff; } - .machine-aps-toolbar { - display: flex; - align-items: center; - gap: 8px; - padding: 10px 12px; - border-bottom: 1px solid #DCDFE6; - background: #FAFBFC; - } - - .machine-aps-toolbar-label { - color: #303133; - font-size: 12px; - font-weight: bold; - } - - .machine-aps-toolbar-tip { - margin-left: 4px; - color: #909399; - font-size: 12px; - } - .machine-aps-empty { height: 460px; line-height: 460px; diff --git a/src/views/SeikoWorkshop/WorkshopAssignment/index.vue b/src/views/SeikoWorkshop/WorkshopAssignment/index.vue index 097533d1..5f76b613 100644 --- a/src/views/SeikoWorkshop/WorkshopAssignment/index.vue +++ b/src/views/SeikoWorkshop/WorkshopAssignment/index.vue @@ -596,6 +596,8 @@ export default { // 确保orderName1已加载 if (this.orderName1.length === 0) { await new Promise(resolve => { + // 修改人:Ld 修改时间:2026-08-05 09:35:00; 补全订单列表查询参数初始化,避免跳转查询时报 param 未定义。 + var param = [] var Data = this.CreateData('11', '生产任务查询_订单信息_列表_查询数据', param) this.ExecDatabase(Data).then(response => { for (let i = 0; i < response.data.length; i++) { @@ -861,6 +863,11 @@ export default { submit() { this.$refs['form'].validate((valid) => { if (valid) { + // 修改人:Ld 修改时间:2026-08-05 09:35:00; 投产数修改时同步校验有效数值,避免空值绕过前端表单。 + if (!Number.isFinite(Number(this.form.投产数)) || Number(this.form.投产数) <= 0) { + this.$message.warning('投产数不能为空且必须大于0') + return + } if (this.productionNum === this.form.投产数) { this.$message.warning('数量未发生改变') } else { @@ -908,7 +915,9 @@ export default { this.$message.warning('设备不能为空') return } - if (row.分配数 === 0) { + // 修改人:Ld 修改时间:2026-08-05 09:35:00; 派工数量为空或非正数时直接拦截,避免空数量进入任务分配表。 + if (!Number.isFinite(Number(row.分配数)) || Number(row.分配数) <= 0) { + this.$message.warning('分配数不能为空且必须大于0') return } if (this.loading2) { diff --git a/src/views/SeikoWorkshop/WorkshopAssignmentMobile/index.vue b/src/views/SeikoWorkshop/WorkshopAssignmentMobile/index.vue index 69f45616..c7301784 100644 --- a/src/views/SeikoWorkshop/WorkshopAssignmentMobile/index.vue +++ b/src/views/SeikoWorkshop/WorkshopAssignmentMobile/index.vue @@ -4,21 +4,30 @@
- - - +
+ + + +
+ +
+
{ + return !query || String(item.label).toLowerCase().indexOf(query) > -1 + }).slice(0, 50).map(item => { + return { + label: item.label, + value: item.label, + orderValue: item.value + } + }) + } }, watch: { machineValue(val) { @@ -338,6 +362,46 @@ export default { } }) }, + handleOrderSelect(item) { + this.orderNameText = item.label + this.orderNameValue = item.orderValue + this.orderSuggestVisible = false + this.pageCurrent = 1 + this.getProductName() + this.searchTable() + }, + handleOrderInput(value) { + const selected = this.orderName1.find(item => item.label === value) + if (selected) { + this.orderNameValue = selected.value + } else { + this.orderNameValue = '' + this.productNameValue = '' + this.productName = [] + } + }, + handleOrderClear() { + this.orderNameText = '' + this.orderNameValue = '' + this.productNameValue = '' + this.productName = [] + this.orderSuggestVisible = false + this.pageCurrent = 1 + this.searchTable() + }, + handleOrderEnter() { + const selected = this.orderName1.find(item => item.label === this.orderNameText) + if (selected) { + this.handleOrderSelect({ + label: selected.label, + orderValue: selected.value + }) + } else { + this.orderSuggestVisible = false + this.pageCurrent = 1 + this.searchTable() + } + }, getProductName() { this.productNameValue = '' this.productName = [] @@ -466,8 +530,9 @@ export default { this.$message.warning('设备不能为空') return } - if (Number(row.分配数) === 0) { - this.$message.warning('分配数不能为0') + // 修改人:Ld 修改时间:2026-08-05 09:35:00; 派工数量为空或非正数时直接拦截,避免空数量进入任务分配表。 + if (!Number.isFinite(Number(row.分配数)) || Number(row.分配数) <= 0) { + this.$message.warning('分配数不能为空且必须大于0') return } if (this.loadingSubmit) { @@ -534,6 +599,11 @@ export default { submit() { this.$refs['form'].validate((valid) => { if (valid) { + // 修改人:Ld 修改时间:2026-08-05 09:35:00; 投产数修改时同步校验有效数值,避免空值绕过前端表单。 + if (!Number.isFinite(Number(this.form.投产数)) || Number(this.form.投产数) <= 0) { + this.$message.warning('投产数不能为空且必须大于0') + return + } if (this.productionNum === this.form.投产数) { this.$message.warning('数量未发生改变') return @@ -689,6 +759,83 @@ export default { min-width: 0; } +.native-order-field { + position: relative; + z-index: 20; + width: 100%; + min-width: 0; + box-sizing: border-box; +} + +.native-order-input { + width: 100%; + height: 32px; + min-width: 0; + padding: 0 34px 0 15px; + border: 1px solid #dcdfe6; + border-radius: 4px; + outline: none; + box-sizing: border-box; + color: #606266; + font-size: 13px; + line-height: 32px; + background: #fff; + -webkit-appearance: none; +} + +.native-order-input:focus { + border-color: #409eff; +} + +.native-order-clear { + position: absolute; + top: 1px; + right: 4px; + width: 30px; + height: 30px; + padding: 0; + border: none; + outline: none; + color: #c0c4cc; + font-size: 20px; + line-height: 30px; + background: transparent; +} + +.native-order-list { + position: absolute; + top: 36px; + right: 0; + left: 0; + z-index: 30; + max-height: 260px; + overflow: auto; + border: 1px solid #dcdfe6; + border-radius: 4px; + box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); + background: #fff; +} + +.native-order-option { + display: block; + width: 100%; + min-height: 34px; + padding: 0 12px; + border: none; + border-bottom: 1px solid #f0f2f5; + outline: none; + box-sizing: border-box; + color: #606266; + font-size: 13px; + line-height: 34px; + text-align: left; + background: #fff; +} + +.native-order-option:active { + background: #ecf5ff; +} + .quick-actions { display: flex; flex-wrap: wrap; diff --git a/static/config.js b/static/config.js index 5f08a7ea..cfb134ac 100644 --- a/static/config.js +++ b/static/config.js @@ -4,9 +4,8 @@ export const name1_config = `OP1000` export const name3_config = `OP2000` export const name4_config = `OP9999` -// 修改人:Ld 修改时间:2026-08-03 16:53:10; 方案一当前仅部署测试库,前端接口切换到测试环境以匹配新增存储过程。 -var url = `http://192.168.1.27:8030` // 测试环境 接口端口号 http://192.168.1.27:8031 测试环境管理系统 用户名称:0001 密码:654321 -// var url = `http://192.168.1.27:8010` // 正式环境 接口端口号 http://192.168.1.27:8001 正式环境管理系统 用户名称:0000 密码:0000 +// var url = `http://192.168.1.27:8030` // 测试环境 接口端口号 http://192.168.1.27:8031 测试环境管理系统 用户名称:0001 密码:654321 +var url = `http://192.168.1.27:8010` // 正式环境 接口端口号 http://192.168.1.27:8001 正式环境管理系统 用户名称:0000 密码:0000 var url1 = `http://192.168.1.27:10006` // 立库数据库的接口端口号 // var url = `http://127.0.0.1:10250` // var url = `http://124.220.15.242:8602`