feat: update MES pages and tracking docs

This commit is contained in:
2026-06-29 18:27:00 +08:00
parent ebee02d103
commit e0e1b5d2bb
59 changed files with 8405 additions and 1398 deletions

View File

@@ -0,0 +1,169 @@
USE [YL_MESDB]
GO
IF COL_LENGTH(N'dbo.基础数据_设备工位点检表', N'名称') IS NULL
ALTER TABLE [dbo].[_设备工位点检表] ADD [] nvarchar(100) NULL
GO
ALTER PROCEDURE [dbo].[_设备信息_增加]
@ nvarchar(50) = NULL,
@ nvarchar(100) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(500) = NULL,
@使 nvarchar(100) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ decimal(18, 4) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(10) = NULL,
@ decimal(18, 4) = NULL,
@ nvarchar(10) = NULL,
@ nvarchar(50) = NULL
AS
BEGIN
SET NOCOUNT ON;
IF ISNULL(@, N'') = N'' BEGIN SELECT '0' AS result, N'公司编码不能为空' AS message; RETURN; END
INSERT INTO [dbo].[_设备工位点检表] ([],[],[],[],[],[],[使],[],[],[],[],[],[],[],[],[],[],[])
VALUES (@,@,@,@,@,@,@使,TRY_CONVERT(date, NULLIF(@, N'')),@,@,@,@,@,@,@,@,@,TRY_CONVERT(date, NULLIF(@, N'')));
SELECT '1' AS result;
END
GO
ALTER PROCEDURE [dbo].[_设备信息_编辑]
@ int = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(100) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(500) = NULL,
@使 nvarchar(100) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ decimal(18, 4) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(10) = NULL,
@ decimal(18, 4) = NULL,
@ nvarchar(10) = NULL,
@ nvarchar(50) = NULL
AS
BEGIN
SET NOCOUNT ON;
UPDATE [dbo].[_设备工位点检表]
SET []=@,[]=@,[]=@,[]=@,[]=@,[使]=@使,[]=TRY_CONVERT(date, NULLIF(@, N'')),[]=@,[]=@,[]=@,[]=@,[]=@,[]=@,[]=@,[]=@,[]=@,[]=TRY_CONVERT(date, NULLIF(@, N''))
WHERE []=@;
SELECT '1' AS result;
END
GO
DECLARE @ TABLE ([] nvarchar(100),[] nvarchar(100),[] nvarchar(50),[] nvarchar(50),[] nvarchar(500),[使] nvarchar(100),[] date,[] nvarchar(50),[] decimal(18,4),[] nvarchar(50));
INSERT INTO @ VALUES (N'气泵(空压机)',N'REALLY-11',N'气泵',N'1.4MPa/YT132S-4',N'最大压力0.8Mpa',N'一楼机加车间','2006-12-31',N'',1,N'停用');
INSERT INTO @ VALUES (N'台钻',N'REALLY-21',N'台钻',N'JW7114',N'φ2-12mm/0.1mm',N'二楼机加车间','2007-01-01',N'',1,NULL);
INSERT INTO @ VALUES (N'数控加工中心',N'REALLY-6',N'加1',N'VDL-600A',N'X600/Y420/Z520/',N'一楼机加车间','2008-12-23',N'',1,NULL);
INSERT INTO @ VALUES (N'普通车床',N'REALLY-1',N'普1',N'CD6240A',N'回转直径400/转速1400/0.04mm',N'一楼机加车间','2010-12-31',N'',1,NULL);
INSERT INTO @ VALUES (N'砂轮机',N'REALLY-19',N'砂轮机',N'MQ3225',N'转速3000/砂轮直径250',N'一楼机加车间','2010-12-31',N'',1,NULL);
INSERT INTO @ VALUES (N'数控车床',N'REALLY-3',N'数2',N'CAK5085di',N'床鞍直径280',N'一楼机加车间','2011-09-29',N'',1,NULL);
INSERT INTO @ VALUES (N'万能外圆磨床',N'REALLY-8',N'磨2',N'MG1420E',N'0.005mm',N'一楼机加车间','2012-03-29',N'',1,NULL);
INSERT INTO @ VALUES (N'数控车床',N'REALLY-2',N'数1',N'CAK3665DI',N'0.01mm',N'一楼机加车间','2013-12-31',N'',1,NULL);
INSERT INTO @ VALUES (N'数显鼓风干燥箱/烤箱',N'REALLY-14',N'烤箱',N'101A-0',NULL,N'二楼装配区','2014-06-05',N'',1,NULL);
INSERT INTO @ VALUES (N'数控车床',N'REALLY-4',N'数3',N'Viva T2c/500',N'0.01mm',N'一楼机加车间','2015-03-17',N'',1,NULL);
INSERT INTO @ VALUES (N'超声波清洗机',N'REALLY-16',N'清洗机',N'FRQ-20100ST',NULL,N'二楼清洗室','2015-04-12',N'',1,NULL);
INSERT INTO @ VALUES (N'抛光机',N'REALLY-44',N'抛光机',N'ZXH-Z615-1/ZXH-756',NULL,N'一楼机加车间','2015-05-17',N'',1,NULL);
INSERT INTO @ VALUES (N'激光打标机',N'REALLY-13',N'打标机',N'骄子LMK-F20',NULL,N'二楼装配区','2016-02-01',N'',1,NULL);
INSERT INTO @ VALUES (N'数控车床',N'REALLY-5',N'数4',N'Viva T2C/500',N'0.01mm',N'一楼机加车间','2018-05-11',N'',1,NULL);
INSERT INTO @ VALUES (N'锯床',N'REALLY-10',N'锯1',N'GZ4232',N'0.1mm',N'一楼机加车间','2018-08-26',N'',1,NULL);
INSERT INTO @ VALUES (N'内燃叉车',N'REALLY-33',N'油叉',N'CPCD30/3.0T',N'3T',N'一楼机加车间','2020-04-15',N'',1,NULL);
INSERT INTO @ VALUES (N'螺杆空压机',N'REALLY-23',N'15KW空压机',N'LU15 Pmi',N'最大压力0.8Mpa',N'一楼空压机室','2020-06-29',N'',1,NULL);
INSERT INTO @ VALUES (N'冷干机',N'已报废',NULL,N'PRIMAK D21',NULL,N'一楼空压机室','2020-06-29',N'',1,N'报废');
INSERT INTO @ VALUES (N'数控车床',N'REALLY-25',N'数5',N'T55M含自动排屑器',N'0.01mm',N'一楼机加车间','2020-11-05',N'',1,NULL);
INSERT INTO @ VALUES (N'立卧两用数控台',N'加1#用',N'加1四轴',N'SKT13170F',N'0.05mm',N'加1设备内','2020-12-10',N'',1,NULL);
INSERT INTO @ VALUES (N'立式加工中心',N'REALLY-26',N'加3',N'VDF-850A',N'0.02mm',N'一楼机加车间','2020-12-10',N'',1,NULL);
INSERT INTO @ VALUES (N'立卧两用数控台',N'加3#用',NULL,N'SKT13200F',N'0.05mm',N'一楼机加车间','2020-12-10',N'',1,NULL);
INSERT INTO @ VALUES (N'带锯床',N'REALLY-31',N'锯2',N'B33',N'0.1mm',N'一楼机加车间','2021-02-01',N'',1,NULL);
INSERT INTO @ VALUES (N'电动攻丝机',N'RELLY-29',N'攻丝机2#',N'SW-U16-L',N'夹头范围M3-M16',N'一楼机加车间','2021-02-28',N'',1,N'停用');
INSERT INTO @ VALUES (N'自动数控穿孔机',N'REALLY-28',N'电火花',N'NC4030高精度线规结构',N'穿孔直径0.8-3.0mm/0.05mm',N'一楼机加车间','2021-03-03',N'',1,NULL);
INSERT INTO @ VALUES (N'立式加工中心',N'REALLY-27',N'加4',N'VDF-850A',N'0.02mm',N'一楼机加车间','2021-03-11',N'',1,NULL);
INSERT INTO @ VALUES (N'摇臂钻床',N'REALLY-30',N'钻床',N'Z3050/16',N'夹头范围3-50',N'一楼机加车间','2021-03-17',N'',1,NULL);
INSERT INTO @ VALUES (N'航车',N'起重机/吊车',N'5T吊',N'YLHC-27',N'5T',N'一楼机加车间','2021-04-05',N'',1,NULL);
INSERT INTO @ VALUES (N'电动叉车',N'REALLY-34',N'1.5T电叉',N'CDD-1525/CPCZ1.5T',N'1.5T',N'二楼机加车间','2021-04-05',N'',1,NULL);
INSERT INTO @ VALUES (N'普通车床',N'REALLY-32',N'普2',N'CDE6150A',N'0.03mm',N'一楼机加车间','2021-09-02',N'',1,NULL);
INSERT INTO @ VALUES (N'数控车床',N'REALLY-36',N'数7',N'T55S',N'0.01mm',N'一楼机加车间','2022-04-03',N'',1,NULL);
INSERT INTO @ VALUES (N'数控车床',N'REALLY-37',N'数8',N'T55S',N'0.01mm',N'一楼机加车间','2022-04-03',N'',1,NULL);
INSERT INTO @ VALUES (N'洗地机',N'RELLY-38',N'洗地机',N'YZ-X2',NULL,N'一楼机加车间','2022-04-29',N'',1,NULL);
INSERT INTO @ VALUES (N'自动上下料设备',N'REALLY-39',N'数8机械人',N'HY2119/HY-JCSXL1-2',NULL,N'一楼机加车间','2022-06-22',N'',1,NULL);
INSERT INTO @ VALUES (N'加工中心',N'REALLY-40',N'加5',N'V11L',N'0.02mm',N'一楼机加车间','2022-12-09',N'',1,NULL);
INSERT INTO @ VALUES (N'转台',N'加5#用',N'加5四轴',N'HR-255N-K',N'0.05mm',N'一楼机加车间','2022-12-22',N'',1,NULL);
INSERT INTO @ VALUES (N'旋转接头',N'数7#数#8用',NULL,N'YQXJ56M-20',N'0.1mm',N'一楼机加车间','2023-02-06',N'',2,NULL);
INSERT INTO @ VALUES (N'中实三爪液压卡盘',N'数7#数#8用',N'液压卡盘',N'CL-06A5',NULL,N'一楼机加车间','2023-02-14',N'',2,NULL);
INSERT INTO @ VALUES (N'套丝机',N'RELLY-41',N'套丝机',N'SQ-50B1',NULL,N'一楼机加车间','2023-03-12',N'',1,NULL);
INSERT INTO @ VALUES (N'线号机',N'REALLY-17',N'线号机',N'LM-550B/LM550E',NULL,N'二楼装配车间','2023-04-22',N'',1,NULL);
INSERT INTO @ VALUES (N'高频加热炉',N'REALLY-42',N'高频加热',N'TGG-35KW进品版',NULL,N'二楼装配车间','2023-08-06',N'',1,NULL);
INSERT INTO @ VALUES (N'普通车床',N'REALLY-43',N'普3',N'CW6163E/1000',N'0.03mm',N'一楼机加车间','2023-08-14',N'',1,NULL);
INSERT INTO @ VALUES (N'光栅尺数显系统',N'普3#用',N'普3数显',N'Z向1100mmX向570mm',NULL,N'一楼机加车间','2023-08-16',N'',1,NULL);
INSERT INTO @ VALUES (N'卧式加工中心',N'REALLY-45',N'卧加1',N'HCN-6000L',N'0.01mm',N'一楼机加车间','2023-11-27',N'',1,NULL);
INSERT INTO @ VALUES (N'姊妹刀功能软件',N'数7#数#8用',N'对刀仪',N'6FC5800-OAM78-OYB0',NULL,N'一楼机加车间','2023-12-03',N'',2,NULL);
INSERT INTO @ VALUES (N'自动料仓',N'机器人用',N'机器人料仓',N'配机械手定制件',NULL,N'一楼机加车间','2024-01-28',N'',1,NULL);
INSERT INTO @ VALUES (N'电动悬挂起重机(欧式)',N'REALLY-46',N'普车吊',N'LX2.8T-7.3M/LD2-70/YJ',N'1.5T',N'一楼机加车间','2024-06-29',N'',1,NULL);
INSERT INTO @ VALUES (N'电动悬挂起重机(欧式)',N'REALLY-47',N'装配吊',N'LX2.8T-7M/LD2-40/OR6',N'1.5T',N'二楼车间装配区','2024-06-29',N'',1,NULL);
INSERT INTO @ VALUES (N'多功能除渣除油一体机',N'REALLY-50',N'除渣除油机',N'FGB-4',NULL,N'一楼机加车间','2024-06-29',N'',1,NULL);
INSERT INTO @ VALUES (N'桥式悬挂起重机',N'REALLY-49',N'原料吊',N'LX2-7m/LD2-70Y/YK',N'1.5T',N'一楼车间库房区','2024-06-29',N'',1,NULL);
INSERT INTO @ VALUES (N'切割剥皮两用机',N'REALLY-60',N'割管机',N'QB-51',NULL,N'二楼车间清洗间','2024-09-29',N'',1,NULL);
INSERT INTO @ VALUES (N'缩管机',N'REALLY-61',N'缩管机',N'KM-91C8-323',NULL,N'二楼车间清洗间','2024-09-29',N'',1,NULL);
INSERT INTO @ VALUES (N'冷冻式干燥机',N'REALLY-59',N'冷干机',N'AD2-10',NULL,N'一楼三坐标室','2024-11-25',N'',1,NULL);
INSERT INTO @ VALUES (N'工业脉冲集尘机',N'REALLY-52',N'磨床除尘机',N'FMCJC-2200',NULL,N'一楼机加车间','2024-11-25',N'',1,NULL);
INSERT INTO @ VALUES (N'闪链云智能物',N'REALLY-58',N'刀具柜',N'智能刀具柜主柜88货道+40侧边格/SCCM-03',NULL,N'一楼机加车间','2024-11-25',N'',1,NULL);
INSERT INTO @ VALUES (N'小锯床',N'REALLY-63',N'小带锯',N'DLY-18F1',N'切割范围45°φ100mm/90°180mm',N'二楼车间装配区','2024-11-25',N'',1,NULL);
INSERT INTO @ VALUES (N'车床桁架机械手',N'REALLY-51',N'数5机械手',N'CNPR-B02/CNPR-3000-B',NULL,N'一楼机加车间','2024-11-29',N'',1,NULL);
INSERT INTO @ VALUES (N'二氧焊机',N'REALLY-55',N'二氧焊机',N'YM-350FR2',NULL,N'一楼车间打磨间','2024-11-29',N'',1,N'停用');
INSERT INTO @ VALUES (N'弯管机',N'REALLY-62',N'弯管机',N'DW38NC',NULL,N'二楼车间装配区','2024-11-29',N'',1,NULL);
INSERT INTO @ VALUES (N'数控机床(多主轴车削中心)',N'REALLY-57',N'数9',N'DUAL TURN200/DT200',N'0.01mm',N'一楼机加车间','2024-12-10',N'',1,NULL);
INSERT INTO @ VALUES (N'外圆磨床',N'REALLY-53',N'磨1',N'M1332B/1000',N'0.005mm',N'一楼机加车间','2024-12-25',N'',1,NULL);
INSERT INTO @ VALUES (N'气动压力机',N'REALLY-64',N'压力机1',N'大双柱63型 推力200KG',NULL,N'二楼车间装配','2024-12-03',N'',1,NULL);
INSERT INTO @ VALUES (N'气动压力机',N'REALLY-65',N'压力机2',N'大双柱63型 推力200KG',NULL,N'二楼车间装配','2024-12-03',N'',1,NULL);
INSERT INTO @ VALUES (N'气动压力机',N'REALLY-66',N'压力机3',N'大双柱63型 推力200KG',NULL,N'二楼车间装配','2024-12-03',N'',1,NULL);
INSERT INTO @ VALUES (N'卡套预装机+模具四套',N'REALLY-67',N'卡套预装机',N'KC-A01',NULL,N'二楼车间装配区','2025-01-01',N'',1,NULL);
INSERT INTO @ VALUES (N'单臂移动式焊烟净化器',N'REALLY-56',N'焊烟净化器',N'LW1201L-030AFLW-C-M1201-030A1',N'3000m³/小时',N'一楼车间打磨间','2025-02-13',N'',1,NULL);
INSERT INTO @ VALUES (N'冷干机',N'REALLY-24替换原冷干机',N'冷干机',N'FX45-230/1/50-CN',NULL,N'一楼空压机室','2025-02-07',N'',1,NULL);
INSERT INTO @ VALUES (N'管型预绝缘端子压接机',N'REALLY-68',N'端子机1',N'MD-E(0.5-4平方',N'压接端子范围0.5-4mm²',N'二楼装配车间','2025-08-29',N'',1,NULL);
INSERT INTO @ VALUES (N'OTUT端子压接机2#',N'REALLY-69',N'端子机2',N'MD-180S/MD-180TUT',N'截面积0.33-0.82mm²',N'二楼装配车间','2025-09-04',N'',1,NULL);
INSERT INTO @ VALUES (N'车床桁架机械手',N'REALLY-70',N'数7机械手',N'CNPR-B02/SX-621',NULL,N'一楼机加车间','2025-08-31',N'',1,NULL);
INSERT INTO @ VALUES (N'氩弧焊机',N'REALLY-71',N'氩弧焊机',N'WSE-315',N'使用焊丝规格φ1.0-3.0mm/电流范围20-315A',N'一楼焊接区','2014-06-03',N'',1,N'停用');
INSERT INTO @ VALUES (N'车床桁架机械手',N'REALLY-74',N'数9机械手',N'CNPR-B02/SX-620',N'0.1mm',N'一楼机加车间','2025-08-31',N'',1,NULL);
INSERT INTO @ VALUES (N'电动悬挂起重机(欧式)',N'REALLY-72',N'阀类吊',N'LX2.8T-6M',N'最大起重2.8T/链长6M',N'二楼阀类测试区','2025-12-04',N'',1,NULL);
INSERT INTO @ VALUES (N'马扎克数控车床',N'REALLY-73',N'数6',N'QTE200/500L',N'12工位刀塔/加工φ290/行程500',N'一楼机加车间','2026-01-10',N'',1,NULL);
INSERT INTO @ VALUES (N'马扎克加工中心',N'REALLY-75',N'加2',N'FF400V/30L',N'X500/Y400/Z400',N'一楼机加车间','2026-02-10',N'',1,NULL);
INSERT INTO @ VALUES (N'电动攻丝机',N'RELLY-54',N'攻丝机1#',N'M3-M20(YZ-20C)',N'夹头范围M3-M20',N'一楼机加车间','2025-12-01',N'',1,NULL);
INSERT INTO @ VALUES (N'手动液压叉车',N'REALLY-76',N'手动搬运车',N'黄色AC540 2.5T',N'最大承重2.5T',N'一楼机加车间','2025-12-11',N'',1,NULL);
INSERT INTO @ VALUES (N'455铜铝型材切割机(全自动)',N'REALLY-77',N'自动切割机',N'455铜铝型材切割机',N'最大切割行程100',N'一楼机加车间','2026-03-09',N'',1,NULL);
INSERT INTO @ VALUES (N'油雾收集器',N'REALLY-78',N'数5用',N'YWJC-LD300',NULL,N'一楼机加车间',NULL,N'',1,NULL);
INSERT INTO @ VALUES (N'油雾收集器',N'REALLY-79',N'数7用',N'YWJC-LD300',NULL,N'一楼机加车间',NULL,N'',1,NULL);
INSERT INTO @ VALUES (N'油雾收集器',N'REALLY-80',N'数8用',N'YWJC-LD300',NULL,N'一楼机加车间',NULL,N'',1,NULL);
INSERT INTO @ VALUES (N'油雾收集器',N'REALLY-81',N'数6用',N'YWJC-LD300',NULL,N'一楼机加车间',NULL,N'',1,NULL);
INSERT INTO @ VALUES (N'油雾收集器',N'REALLY-82',N'加2用',N'YWJC-LD1100',NULL,N'一楼机加车间',NULL,N'',1,NULL);
INSERT INTO @ VALUES (N'油雾收集器',N'REALLY-83',N'加3用',N'YWJC-LD1100',NULL,N'一楼机加车间',NULL,N'',1,NULL);
INSERT INTO @ VALUES (N'油雾收集器',N'REALLY-84',N'加5用',N'YWJC-LD1100',NULL,N'一楼机加车间',NULL,N'',1,NULL);
INSERT INTO @ VALUES (N'油雾收集器',N'REALLY-85',N'卧加用',N'YWJC-LD1500',NULL,N'一楼机加车间',NULL,N'',1,NULL);
INSERT INTO @ VALUES (N'油雾收集器',N'REALLY-86',N'数9用',N'YWJC-LD600',NULL,N'一楼机加车间',NULL,N'',1,NULL);
INSERT INTO @ VALUES (N'无尘环保带锯床',N'REALLY-87',N'小带锯2#',N'DLY-18F1',N'45°切割范围φ100',N'一楼机打磨间','2026-05-20',N'',1,NULL);
INSERT INTO @ VALUES (N'车床桁架机械手',N'REALLY-88',N'数6机械手',N'CNPR-B03',NULL,N'一楼机加车间',NULL,N'',1,NULL);
MERGE [dbo].[_设备工位点检表] AS target
USING @ AS source
ON ISNULL(target.[], N'') = ISNULL(source.[], N'') AND ISNULL(source.[], N'') <> N''
WHEN MATCHED THEN UPDATE SET
target.[]=source.[], target.[]=source.[], target.[]=source.[], target.[]=source.[], target.[使]=source.[使], target.[]=source.[], target.[]=source.[], target.[]=source.[], target.[]=source.[]
WHEN NOT MATCHED BY TARGET THEN
INSERT ([],[],[],[],[],[使],[],[],[],[])
VALUES (source.[],source.[],source.[],source.[],source.[],source.[使],source.[],source.[],source.[],source.[]);
GO
SELECT COUNT(*) AS [] FROM [dbo].[_设备工位点检表];
GO

View File

@@ -0,0 +1,43 @@
USE [YL_MESDB]
GO
DECLARE @NewMenuId INT;
SELECT @NewMenuId = MAX(id)
FROM [dbo].[_二级菜单]
WHERE title = N'结算工时'
OR componet = '/ProductionManagement/SettlementWorkhours/index';
IF @NewMenuId IS NULL
BEGIN
SELECT @NewMenuId = ISNULL(MAX(id), 0) + 1
FROM [dbo].[_二级菜单];
END;
INSERT INTO [dbo].[_二级菜单]
(id, pid, path, componet, redirect, name, title, icon, , , , AddData, DeleteData, EditData, SearchData)
SELECT
@NewMenuId AS id,
3 AS pid,
'SettlementWorkhours/index' AS path,
'/ProductionManagement/SettlementWorkhours/index' AS componet,
'' AS redirect,
'SettlementWorkhours' AS name,
N'结算工时' AS title,
ISNULL(NULLIF(w.icon, ''), 'DimensionsSummaryReport') AS icon,
w.,
w.,
ISNULL(w., 1) AS ,
w.AddData,
w.DeleteData,
w.EditData,
w.SearchData
FROM [dbo].[_二级菜单] w
WHERE w.title = N'工时查询'
AND NOT EXISTS (
SELECT 1
FROM [dbo].[_二级菜单] existing
WHERE existing.title = N'结算工时'
AND existing. = w.
);
GO

View File

@@ -0,0 +1,85 @@
USE [YL_MESDB]
GO
SET NOCOUNT ON;
DECLARE @Title nvarchar(100) = N'及时齐套跟踪结果';
DECLARE @Path nvarchar(300) = N'TimelyKitTrackingResult/index';
DECLARE @Component nvarchar(300) = N'/PlanManagement/TimelyKitTrackingResult/index';
DECLARE @Name nvarchar(100) = N'TimelyKitTrackingResult';
DECLARE @SourcePath nvarchar(300) = N'PlanShell/index';
DECLARE @SourceComponent nvarchar(300) = N'/PlanManagement/PlanShell/index';
IF OBJECT_ID(N'dbo.登录基础数据_二级菜单', N'U') IS NULL
BEGIN
RAISERROR(N'未找到表 dbo.登录基础数据_二级菜单。', 16, 1);
RETURN;
END;
DECLARE @IdIsIdentity bit = ISNULL(COLUMNPROPERTY(OBJECT_ID(N'dbo.登录基础数据_二级菜单'), N'id', 'IsIdentity'), 0);
IF @IdIsIdentity = 1
BEGIN
;WITH SourceRows AS (
SELECT
src.[],
src.[pid],
src.[icon]
FROM [dbo].[_二级菜单] src
WHERE src.[] = 1
AND (src.[path] = @SourcePath OR src.[componet] = @SourceComponent OR src.[title] = N'计划用表')
AND NOT EXISTS (
SELECT 1
FROM [dbo].[_二级菜单] existing
WHERE existing.[] = src.[]
AND (existing.[path] = @Path OR existing.[componet] = @Component OR existing.[title] = @Title)
)
)
INSERT INTO [dbo].[_二级菜单]
([pid], [path], [componet], [redirect], [name], [title], [icon], [], [])
SELECT [pid], @Path, @Component, NULL, @Name, @Title, [icon], [], 1
FROM SourceRows;
END
ELSE
BEGIN
;WITH SourceRows AS (
SELECT
ROW_NUMBER() OVER (ORDER BY src.[], src.[id]) AS rn,
src.[],
src.[pid],
src.[icon]
FROM [dbo].[_二级菜单] src
WHERE src.[] = 1
AND (src.[path] = @SourcePath OR src.[componet] = @SourceComponent OR src.[title] = N'计划用表')
AND NOT EXISTS (
SELECT 1
FROM [dbo].[_二级菜单] existing
WHERE existing.[] = src.[]
AND (existing.[path] = @Path OR existing.[componet] = @Component OR existing.[title] = @Title)
)
),
BaseId AS (
SELECT ISNULL(MAX([id]), 0) AS maxId
FROM [dbo].[_二级菜单]
)
INSERT INTO [dbo].[_二级菜单]
([id], [pid], [path], [componet], [redirect], [name], [title], [icon], [], [])
SELECT BaseId.maxId + SourceRows.rn, SourceRows.[pid], @Path, @Component, NULL, @Name, @Title, SourceRows.[icon], SourceRows.[], 1
FROM SourceRows
CROSS JOIN BaseId;
END;
UPDATE [dbo].[_二级菜单]
SET
[path] = @Path,
[componet] = @Component,
[name] = @Name,
[title] = @Title,
[] = [id],
[] = 1
WHERE [title] = @Title OR [componet] = @Component;
SELECT [id], [pid], [path], [componet], [name], [title], [icon], [], []
FROM [dbo].[_二级菜单]
WHERE [path] = @Path OR [componet] = @Component OR [title] = @Title
ORDER BY [], [id];

View File

@@ -0,0 +1,231 @@
USE [YL_MESDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF OBJECT_ID(N'[dbo].[生产管理_结算工时_查询]', N'P') IS NULL
EXEC(N'CREATE PROCEDURE [dbo].[生产管理_结算工时_查询] AS BEGIN SET NOCOUNT ON; END')
GO
ALTER PROCEDURE [dbo].[_结算工时_查询]
@ NVARCHAR(50) = NULL,
@ NVARCHAR(100) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ DATE = NULL,
@ DATE = NULL,
@ INT = 100
AS
BEGIN
SET NOCOUNT ON;
;WITH AS (
SELECT
AID,
,
,
FROM [dbo].[MES_接口_生产计划]
WHERE IS NULL
),
AS (
SELECT TOP (CASE WHEN ISNULL(@, 0) <= 0 THEN 100 ELSE @ END)
v.TaskAID,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
p.,
p.
FROM [dbo].[View_生产工时视图] v
INNER JOIN p ON p.AID = v.TaskAID
WHERE (@ IS NULL OR @ = '' OR v. >= @)
AND (@ IS NULL OR @ = '' OR v. < DATEADD(DAY, 1, @))
AND (@ IS NULL OR @ = '' OR v. LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR v. LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR v. = @)
AND (@ IS NULL OR @ = '' OR v. LIKE '%' + @ + '%')
AND ISNULL(v., 0) > 0
AND (ISNULL(v., '') IN ('报工', '辅助结束') OR ISNULL(v., '') IN ('报工', '辅助结束'))
ORDER BY v. DESC
),
AS (
SELECT DISTINCT
TaskAID,
CONVERT(VARCHAR(19), , 120) AS
FROM
),
AS (
SELECT
k.TaskAID,
k.,
LTRIM(RTRIM(s.value)) AS
FROM k
INNER JOIN [dbo].[View_生产工时视图全部] v2
ON v2.TaskAID = k.TaskAID
AND v2. >= CONVERT(DATETIME, k., 120)
AND v2. < DATEADD(SECOND, 1, CONVERT(DATETIME, k., 120))
CROSS APPLY STRING_SPLIT(REPLACE(REPLACE(ISNULL(v2., ''), N'', ','), N'', ','), ',') s
WHERE ISNULL(v2., 0) <= 0
AND NULLIF(LTRIM(RTRIM(s.value)), '') IS NOT NULL
),
AS (
SELECT
TaskAID,
,
STRING_AGG(, ',') AS
FROM (
SELECT DISTINCT TaskAID, ,
FROM
) x
GROUP BY TaskAID,
),
AS (
SELECT
ISNULL(b., b.) AS ,
ISNULL(b., b.) AS ,
b.,
b.,
b.TaskAID,
b.,
b.,
ISNULL(o., '') AS ,
CASE
WHEN ISNULL(b., '') LIKE '%辅助%' OR ISNULL(b., '') LIKE '%辅助%' THEN '辅助结束'
ELSE '报工'
END AS ,
CAST(ISNULL(b., 0) / 60.0 / 60.0 AS DECIMAL(18, 4)) AS ,
ISNULL(b., 0) AS
FROM b
LEFT JOIN o
ON o.TaskAID = b.TaskAID
AND o. = CONVERT(VARCHAR(19), b., 120)
),
AS (
SELECT
,
,
,
,
MAX() AS ,
MAX() AS ,
COUNT(*) AS ,
SUM(CASE WHEN = '报工' THEN ELSE 0 END) AS ,
SUM(CASE WHEN = '辅助结束' THEN ELSE 0 END) AS ,
SUM(CASE WHEN = '报工' THEN ELSE 0 END) AS ,
SUM(CASE WHEN = '辅助结束' THEN ELSE 0 END) AS ,
SUM() AS
FROM j
GROUP BY , , ,
),
AS (
SELECT
,
,
ISNULL(, '') AS ,
STRING_AGG(, ',') AS
FROM (
SELECT DISTINCT
j.,
j.,
ISNULL(j., '') AS ,
LTRIM(RTRIM(s.value)) AS
FROM j
CROSS APPLY STRING_SPLIT(REPLACE(REPLACE(ISNULL(j., ''), N'', ','), N'', ','), ',') s
WHERE NULLIF(LTRIM(RTRIM(s.value)), '') IS NOT NULL
) x
GROUP BY , , ISNULL(, '')
),
AS (
SELECT
b.,
b.,
b.,
b.,
b.,
b.,
b.,
b.,
b.,
b.,
b.,
b.,
ISNULL(o., '') AS
FROM b
LEFT JOIN o
ON o. = b.
AND o. = b.
AND o. = ISNULL(b., '')
),
AS (
SELECT
,
,
SUM() AS ,
SUM() AS ,
SUM() AS ,
SUM() AS ,
SUM() AS ,
SUM() AS
FROM
GROUP BY ,
)
SELECT
1 AS [Level],
AS materialCode,
AS materialDesc,
ISNULL(, '') + ' ' + ISNULL(, '') AS taskDescription,
'' AS productionOrderNo,
'' AS station,
CAST( AS VARCHAR(20)) AS reportWorkHours,
CAST( AS VARCHAR(20)) AS auxiliaryWorkHours,
CAST( AS VARCHAR(20)) AS reportFinishQty,
CAST( AS VARCHAR(20)) AS auxiliaryFinishQty,
CAST( AS VARCHAR(20)) AS totalWorkHours,
CAST(CASE WHEN > 0 THEN ( - 0 * ) / ELSE 0 END AS VARCHAR(20)) AS clampingTime,
CAST(0 AS VARCHAR(20)) AS programTime,
CAST(CASE WHEN > 0 THEN / ELSE 0 END AS VARCHAR(20)) AS settlementReportPieceHours,
CAST(CASE WHEN > 0 THEN / ELSE 0 END AS VARCHAR(20)) AS settlementAuxiliaryPieceHours,
'' AS operatorNames,
CAST( AS VARCHAR(20)) AS recordCount
FROM
UNION ALL
SELECT
2 AS [Level],
AS materialCode,
AS materialDesc,
ISNULL(, '') + ' ' + ISNULL(, '')
+ CASE WHEN NULLIF(ISNULL(, ''), '') IS NULL THEN '' ELSE ' ' + END
+ CASE WHEN IS NULL THEN '' ELSE '' + CAST( AS VARCHAR(20)) END AS taskDescription,
ISNULL(, '') AS productionOrderNo,
ISNULL(, '') AS station,
CAST( AS VARCHAR(20)) AS reportWorkHours,
CAST( AS VARCHAR(20)) AS auxiliaryWorkHours,
CAST( AS VARCHAR(20)) AS reportFinishQty,
CAST( AS VARCHAR(20)) AS auxiliaryFinishQty,
CAST( AS VARCHAR(20)) AS totalWorkHours,
CAST(CASE WHEN > 0 THEN ( - 0 * ) / ELSE 0 END AS VARCHAR(20)) AS clampingTime,
CAST(0 AS VARCHAR(20)) AS programTime,
CAST(CASE WHEN > 0 THEN / ELSE 0 END AS VARCHAR(20)) AS settlementReportPieceHours,
CAST(CASE WHEN > 0 THEN / ELSE 0 END AS VARCHAR(20)) AS settlementAuxiliaryPieceHours,
ISNULL(, '') AS operatorNames,
CAST( AS VARCHAR(20)) AS recordCount
FROM
ORDER BY materialCode, [Level], productionOrderNo, station
END
GO

View File

@@ -0,0 +1,410 @@
USE [YL_MESDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF OBJECT_ID(N'dbo.生产管理_及时齐套跟踪结果_查询', N'P') IS NULL
BEGIN
EXEC(N'CREATE PROCEDURE [dbo].[生产管理_及时齐套跟踪结果_查询] AS BEGIN SET NOCOUNT ON; END');
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[_及时齐套跟踪结果_查询]
@ int = 0,
@ nvarchar(50) = N'',
@ nvarchar(50) = N'',
@ nvarchar(50) = N'',
@ nvarchar(50) = N'',
@ nvarchar(50) = N'',
@ nvarchar(50) = N'',
@ nvarchar(50) = N'',
@ nvarchar(50) = N'全部',
@ nvarchar(50) = N'全部',
@ nvarchar(50) = N'',
@ nvarchar(50) = N'全部',
@ nvarchar(50) = N'全部',
@ nvarchar(50) = N'',
@ nvarchar(50) = N'全部',
@ nvarchar(50) = N'全部'
AS
BEGIN
SET NOCOUNT ON;
;WITH SAP缺件源 AS (
SELECT
s.DocEntry,
s.Project COLLATE DATABASE_DEFAULT AS Project,
s.[],
s.ItemCode COLLATE DATABASE_DEFAULT AS ItemCode,
s.U_Name COLLATE DATABASE_DEFAULT AS U_Name,
ISNULL(s.[] COLLATE DATABASE_DEFAULT, N'') AS ,
ISNULL(s.[], 0) AS ,
ISNULL(s.[], 0) AS ,
s.[] COLLATE DATABASE_DEFAULT AS ,
s.[],
ISNULL(s.[], 0) AS ,
ISNULL(s.[稿], 0) AS 稿
FROM [SAP].[SBO_YL].[dbo].[VIEW_Jijiankukc] AS s
WHERE ISNULL(s.[], 0) > 0
),
SAP缺件 AS (
SELECT TOP (2000)
src.*
FROM (
SELECT
SAP缺件源.*,
ROW_NUMBER() OVER (
PARTITION BY
SAP缺件源.DocEntry,
SAP缺件源.Project,
SAP缺件源.ItemCode,
SAP缺件源.
ORDER BY
SAP缺件源.[] DESC,
SAP缺件源.[]
) AS rn
FROM SAP缺件源
) AS src
WHERE src.rn = 1
),
AS (
SELECT
ISNULL(v.[], N'') AS [],
ISNULL(v.[], N'') AS [],
v.[] AS [],
v.[] AS [],
v.[] AS [],
v.[],
v.[],
v.[] AS [],
v.[],
CASE
WHEN ISNULL(v.[], 0) = 1 THEN N'已发货'
ELSE N'未发货'
END AS [],
CASE
WHEN ISNULL(v.[], 0) = 1 THEN N''
ELSE N''
END AS [],
CASE
WHEN ISNULL(v.[], 0) = 1 THEN N'已拣配'
ELSE N'未拣配'
END AS [],
CASE
WHEN ISNULL(v.[], N'') = N'1' THEN N'发料齐套'
WHEN ISNULL(v.[], N'') = N'2' THEN N'发料缺件'
ELSE N'未发料'
END AS [],
CASE
WHEN ISNULL(v.[], 0) IN (2, 4) OR v.[] > '1900-01-01' THEN N'已开工'
ELSE N'待执行'
END AS [],
v.[],
CASE
WHEN final_check.[] IS NOT NULL THEN N''
ELSE N''
END AS [],
CASE WHEN ISNULL(v.[], 0) = 1 THEN N'' ELSE N'' END AS [],
CASE WHEN ISNULL(v.[], 0) = 1 THEN N'已排产' ELSE N'未排产' END AS [],
ISNULL(v.[], N'') AS [],
v.[] AS [],
sap.ItemCode AS [],
sap.U_Name AS [],
sap.[] AS [],
CASE WHEN sap.[] = N'' THEN N'外购' ELSE sap.[] END AS [],
CASE
WHEN sap.[] = N'' THEN ISNULL(CONVERT(nvarchar(50), NULLIF(sap.[稿], 0)), N'')
ELSE ISNULL(CONVERT(nvarchar(50), detail_order.[]), N'')
END AS [],
CASE WHEN sap.[] = N'' THEN N'' ELSE ISNULL(current_step.[], N'') END AS [],
CASE
WHEN sap.[] = N'' THEN
N'采购员:' + ISNULL(NULLIF(sap.[], N''), N'-') +
N' / 未清数量:' + CONVERT(nvarchar(30), sap.[]) +
N' / 到货草稿:' + CONVERT(nvarchar(30), sap.[稿]) +
N' / 质检状态:' + ISNULL(purchase_check.[], N'未完成')
ELSE ISNULL(route.[线], N'')
END AS [线],
CASE
WHEN sap.[] = N'' THEN sap.[]
ELSE route.[]
END AS [],
CASE WHEN sap.[] = N'' THEN N'' ELSE ISNULL(route.[线], N'[]') END AS [线],
sap.[],
sap.[],
sap.[稿],
ISNULL(purchase_check.[], CASE WHEN sap.[] = N'' THEN N'未完成' ELSE N'' END) AS [],
sap.DocEntry AS [SAP单据],
sap.[] AS [SAP行号]
FROM SAP缺件 AS sap
OUTER APPLY (
SELECT TOP (1) m.*
FROM [dbo].[View_生产订单_MES] AS m
WHERE m.[] = N'pit_Resource'
AND ISNULL(m.[], 0) = 1
AND m.[] = sap.DocEntry
ORDER BY m.[]
) AS v
OUTER APPLY (
SELECT TOP (1) m.*
FROM [dbo].[View_生产订单_MES] AS m
WHERE m.[] = N'pit_Resource'
AND ISNULL(m.[], 0) = 1
AND m.[] <> v.[]
AND (
(sap.[] = N'机加件' AND m.[] = sap.ItemCode)
OR (sap.[] LIKE N'%装配%' AND m.[] = sap.ItemCode AND ISNULL(m.[], N'') = ISNULL(sap.Project, N''))
)
ORDER BY m.[] DESC, m.[]
) AS detail_order
OUTER APPLY (
SELECT TOP (1) q.[]
FROM [dbo].[YL_质量检验_质检记录] AS q
WHERE q.[] = N'终检'
AND q.[] = v.[]
) AS final_check
OUTER APPLY (
SELECT
MAX(p.[]) AS [],
STUFF((
SELECT N'' + p2.[] +
CASE WHEN ISNULL(p2.[], N'') = N'' THEN N'' ELSE N'(' + p2.[] + N')' END
FROM [dbo].[View_生产订单_MES] AS p2
WHERE p2.[] = detail_order.[]
AND p2.[] = N'pit_Resource'
ORDER BY p2.[]
FOR XML PATH(N''), TYPE
).value(N'.', N'nvarchar(max)'), 1, 1, N'') AS [线],
(
SELECT
p2.[],
p2.[],
p2.[],
p2.[],
p2.[],
ISNULL(p2.[], 0) AS [],
ISNULL(p2.[], 0) AS [],
ISNULL(p2.[], 0) AS [],
ISNULL(p2.[], 0) AS [],
p2.[],
ISNULL(check_qty.[], 0) AS [],
ISNULL(check_qty.[], 0) AS []
FROM [dbo].[View_生产订单_MES] AS p2
OUTER APPLY (
SELECT
SUM(ISNULL(q.[], 0)) AS [],
SUM(ISNULL(q.[], 0)) AS []
FROM [dbo].[YL_质量检验_质检记录] AS q
WHERE q.[TaskAID] = p2.[TaskAID]
AND q.[] = N'收检'
) AS check_qty
WHERE p2.[] = detail_order.[]
AND p2.[] = N'pit_Resource'
ORDER BY p2.[]
FOR JSON PATH
) AS [线]
FROM [dbo].[View_生产订单_MES] AS p
WHERE p.[] = detail_order.[]
AND p.[] = N'pit_Resource'
) AS route
OUTER APPLY (
SELECT TOP (1)
pending.[],
pending.[],
pending.[],
pending.[],
pending.[],
pending.[],
pending.[]
FROM [dbo].[View_生产订单_MES] AS pending
WHERE pending.[] = detail_order.[]
AND pending.[] = N'pit_Resource'
AND NOT (
ISNULL(pending.[], 0) >= 100
OR (ISNULL(pending.[], 0) > 0 AND ISNULL(pending.[], 0) >= ISNULL(pending.[], 0))
)
ORDER BY pending.[]
) AS pending
OUTER APPLY (
SELECT TOP (1) prev.[]
FROM [dbo].[View_生产订单_MES] AS prev
WHERE prev.[] = detail_order.[]
AND prev.[] = N'pit_Resource'
AND prev.[] < pending.[]
ORDER BY prev.[] DESC
) AS prev_step
OUTER APPLY (
SELECT TOP (1) last_step.[]
FROM [dbo].[View_生产订单_MES] AS last_step
WHERE last_step.[] = detail_order.[]
AND last_step.[] = N'pit_Resource'
ORDER BY last_step.[] DESC
) AS last_step
OUTER APPLY (
SELECT
CASE
WHEN detail_order.[] IS NULL THEN N''
WHEN pending.[] IS NULL THEN ISNULL(last_step.[], N'') + N''
WHEN ISNULL(pending.[], 0) > 0
OR ISNULL(pending.[], 0) > 0
OR ISNULL(pending.[], 0) IN (2, 3, 4, 5, 6)
OR pending.[] > '1900-01-01'
THEN ISNULL(pending.[], N'') + N''
WHEN prev_step.[] IS NULL THEN N''
ELSE prev_step.[] + N'毕待' + ISNULL(pending.[], N'')
END AS []
) AS current_step
OUTER APPLY (
SELECT
CASE
WHEN sap.[] <> N'' THEN N''
WHEN EXISTS (
SELECT 1
FROM [dbo].[_质检任务_SAP] AS task
OUTER APPLY (
SELECT SUM(ISNULL(q.[], 0)) AS []
FROM [dbo].[YL_质量检验_质检记录] AS q
WHERE q.[] = 5
AND q.[] = task.[]
AND q.[] = task.[]
AND q.[] = task.[]
) AS checked_qty
WHERE sap.[稿] > 0
AND task.[] = N'20'
AND task.[] = sap.[稿]
AND ISNULL(task.[], 0) > 0
)
AND NOT EXISTS (
SELECT 1
FROM [dbo].[_质检任务_SAP] AS task
OUTER APPLY (
SELECT SUM(ISNULL(q.[], 0)) AS []
FROM [dbo].[YL_质量检验_质检记录] AS q
WHERE q.[] = 5
AND q.[] = task.[]
AND q.[] = task.[]
AND q.[] = task.[]
) AS checked_qty
WHERE sap.[稿] > 0
AND task.[] = N'20'
AND task.[] = sap.[稿]
AND (
ISNULL(task.[], 0) <= 0
OR ISNULL(checked_qty.[], 0) < ISNULL(task.[], 0)
)
) THEN N'已完成'
ELSE N'未完成'
END AS []
) AS purchase_check
WHERE
v.[] IS NOT NULL
AND (@ <= 0 OR v.[] = @)
AND (@ = N'' OR ISNULL(v.[], N'') = @)
AND (@ = N'' OR ISNULL(v.[], N'') LIKE N'%' + @ + N'%')
AND (@ = N'' OR ISNULL(v.[], N'') LIKE N'%' + @ + N'%')
AND (@ = N'' OR ISNULL(v.[], N'') LIKE N'%' + @ + N'%')
AND (@ = N'' OR EXISTS (
SELECT 1
FROM [dbo].[View_生产订单_MES] AS fp
WHERE fp.[] = v.[]
AND fp.[] = @
))
AND (@ = N'' OR v.[] >= TRY_CONVERT(datetime, @))
AND (@ = N'' OR v.[] <= TRY_CONVERT(datetime, @))
AND (@ = N'全部' OR @ = N'' OR
(@ = N'已完成' AND ISNULL(v.[], 0) = 1) OR
(@ = N'未完成' AND ISNULL(v.[], 0) = 0)
)
AND (@ = N'全部' OR @ = N'' OR EXISTS (
SELECT 1
FROM [dbo].[View_生产订单_MES] AS ap
WHERE ap.[] = v.[]
AND ap.[] IN (SELECT LTRIM(RTRIM(value)) FROM STRING_SPLIT(@, N','))
))
AND (@ = N'全部' OR @ = N'' OR
(@ = N'已发货' AND ISNULL(v.[], N'0') = N'1') OR
(@ = N'未发货' AND ISNULL(v.[], N'0') <> N'1')
)
AND (@ = N'全部' OR @ = N'' OR
(@ = N'' AND ISNULL(v.[], 0) = 1) OR
(@ = N'' AND ISNULL(v.[], 0) <> 1)
)
AND (@ = N'全部' OR @ = N'' OR
(@ = N'发料齐套' AND ISNULL(v.[], N'0') = N'1') OR
(@ = N'发料缺件' AND ISNULL(v.[], N'0') = N'2') OR
(@ = N'未发料' AND ISNULL(v.[], N'0') NOT IN (N'1', N'2'))
)
AND (@ = N'全部' OR @ = N'' OR
(@ = N'机加' AND (sap.[] = N'机加件' OR v.[] = N'机加件')) OR
(@ = N'装配' AND (sap.[] LIKE N'%装配%' OR v.[] LIKE N'%装配%'))
)
AND (@ = N'' OR (sap.[] = N'' AND ISNULL(purchase_check.[], N'') = @))
)
SELECT TOP (1000)
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[线],
[],
[线],
[],
[],
[稿],
[],
[SAP单据],
[SAP行号]
FROM (
SELECT
.*,
ROW_NUMBER() OVER (
PARTITION BY
[],
CASE
WHEN ISNULL([], N'') <> N'' THEN []
ELSE [] + N':' + CONVERT(nvarchar(30), [SAP行号])
END
ORDER BY [] DESC, [SAP单据], [SAP行号]
) AS rn
FROM
) AS dedup
WHERE rn = 1
ORDER BY
[],
[],
[],
[];
END
GO

View File

@@ -0,0 +1,76 @@
USE [YL_MESDB]
GO
ALTER PROCEDURE [dbo].[_设备信息_增加]
@ nvarchar(50) = NULL,
@ nvarchar(100) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(500) = NULL,
@使 nvarchar(100) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ decimal(18, 4) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(10) = NULL,
@ decimal(18, 4) = NULL,
@ nvarchar(10) = NULL,
@ nvarchar(50) = NULL
AS
BEGIN
SET NOCOUNT ON;
IF ISNULL(@, N'') = N''
BEGIN
SELECT '0' AS result, N'公司编码不能为空' AS message;
RETURN;
END
INSERT INTO [dbo].[_设备工位点检表] (
[],
[],
[],
[],
[],
[],
[使],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[]
)
VALUES (
@,
@,
@,
@,
@,
@,
@使,
TRY_CONVERT(date, NULLIF(@, N'')),
@,
@,
@,
@,
@,
@,
@,
@,
@,
TRY_CONVERT(date, NULLIF(@, N''))
);
SELECT '1' AS result;
END
GO

View File

@@ -0,0 +1,96 @@
USE [YL_MESDB]
GO
DECLARE @ TABLE ([] nvarchar(100), [] date);
INSERT INTO @ VALUES (N'REALLY-11', '2007-01-01');
INSERT INTO @ VALUES (N'REALLY-21', '2007-01-02');
INSERT INTO @ VALUES (N'REALLY-6', '2008-12-24');
INSERT INTO @ VALUES (N'REALLY-1', '2011-01-01');
INSERT INTO @ VALUES (N'REALLY-19', '2011-01-01');
INSERT INTO @ VALUES (N'REALLY-3', '2011-09-30');
INSERT INTO @ VALUES (N'REALLY-8', '2012-03-30');
INSERT INTO @ VALUES (N'REALLY-2', '2014-01-01');
INSERT INTO @ VALUES (N'REALLY-14', '2014-06-06');
INSERT INTO @ VALUES (N'REALLY-4', '2015-03-18');
INSERT INTO @ VALUES (N'REALLY-16', '2015-04-13');
INSERT INTO @ VALUES (N'REALLY-44', '2015-05-18');
INSERT INTO @ VALUES (N'REALLY-13', '2016-02-02');
INSERT INTO @ VALUES (N'REALLY-5', '2018-05-12');
INSERT INTO @ VALUES (N'REALLY-10', '2018-08-27');
INSERT INTO @ VALUES (N'REALLY-33', '2020-04-16');
INSERT INTO @ VALUES (N'REALLY-23', '2020-06-30');
INSERT INTO @ VALUES (N'已报废', '2020-06-30');
INSERT INTO @ VALUES (N'REALLY-25', '2020-11-06');
INSERT INTO @ VALUES (N'加1#用', '2020-12-11');
INSERT INTO @ VALUES (N'REALLY-26', '2020-12-11');
INSERT INTO @ VALUES (N'加3#用', '2020-12-11');
INSERT INTO @ VALUES (N'REALLY-31', '2021-02-02');
INSERT INTO @ VALUES (N'RELLY-29', '2021-03-01');
INSERT INTO @ VALUES (N'REALLY-28', '2021-03-04');
INSERT INTO @ VALUES (N'REALLY-27', '2021-03-12');
INSERT INTO @ VALUES (N'REALLY-30', '2021-03-18');
INSERT INTO @ VALUES (N'起重机/吊车', '2021-04-06');
INSERT INTO @ VALUES (N'REALLY-34', '2021-04-06');
INSERT INTO @ VALUES (N'REALLY-32', '2021-09-03');
INSERT INTO @ VALUES (N'REALLY-36', '2022-04-04');
INSERT INTO @ VALUES (N'REALLY-37', '2022-04-04');
INSERT INTO @ VALUES (N'RELLY-38', '2022-04-30');
INSERT INTO @ VALUES (N'REALLY-39', '2022-06-23');
INSERT INTO @ VALUES (N'REALLY-40', '2022-12-10');
INSERT INTO @ VALUES (N'加5#用', '2022-12-23');
INSERT INTO @ VALUES (N'数7#数#8用', '2023-02-07');
INSERT INTO @ VALUES (N'数7#数#8用', '2023-02-15');
INSERT INTO @ VALUES (N'RELLY-41', '2023-03-13');
INSERT INTO @ VALUES (N'REALLY-17', '2023-04-23');
INSERT INTO @ VALUES (N'REALLY-42', '2023-08-07');
INSERT INTO @ VALUES (N'REALLY-43', '2023-08-15');
INSERT INTO @ VALUES (N'普3#用', '2023-08-17');
INSERT INTO @ VALUES (N'REALLY-45', '2023-11-28');
INSERT INTO @ VALUES (N'数7#数#8用', '2023-12-04');
INSERT INTO @ VALUES (N'机器人用', '2024-01-29');
INSERT INTO @ VALUES (N'REALLY-46', '2024-06-30');
INSERT INTO @ VALUES (N'REALLY-47', '2024-06-30');
INSERT INTO @ VALUES (N'REALLY-50', '2024-06-30');
INSERT INTO @ VALUES (N'REALLY-49', '2024-06-30');
INSERT INTO @ VALUES (N'REALLY-60', '2024-09-30');
INSERT INTO @ VALUES (N'REALLY-61', '2024-09-30');
INSERT INTO @ VALUES (N'REALLY-59', '2024-11-26');
INSERT INTO @ VALUES (N'REALLY-52', '2024-11-26');
INSERT INTO @ VALUES (N'REALLY-58', '2024-11-26');
INSERT INTO @ VALUES (N'REALLY-63', '2024-11-26');
INSERT INTO @ VALUES (N'REALLY-51', '2024-11-30');
INSERT INTO @ VALUES (N'REALLY-55', '2024-11-30');
INSERT INTO @ VALUES (N'REALLY-62', '2024-11-30');
INSERT INTO @ VALUES (N'REALLY-57', '2024-12-11');
INSERT INTO @ VALUES (N'REALLY-53', '2024-12-26');
INSERT INTO @ VALUES (N'REALLY-64', '2024-12-04');
INSERT INTO @ VALUES (N'REALLY-65', '2024-12-04');
INSERT INTO @ VALUES (N'REALLY-66', '2024-12-04');
INSERT INTO @ VALUES (N'REALLY-67', '2025-01-02');
INSERT INTO @ VALUES (N'REALLY-56', '2025-02-14');
INSERT INTO @ VALUES (N'REALLY-24替换原冷干机', '2025-02-08');
INSERT INTO @ VALUES (N'REALLY-68', '2025-08-30');
INSERT INTO @ VALUES (N'REALLY-69', '2025-09-05');
INSERT INTO @ VALUES (N'REALLY-70', '2025-09-01');
INSERT INTO @ VALUES (N'REALLY-71', '2014-06-04');
INSERT INTO @ VALUES (N'REALLY-74', '2025-09-01');
INSERT INTO @ VALUES (N'REALLY-72', '2025-12-04');
INSERT INTO @ VALUES (N'REALLY-73', '2026-01-10');
INSERT INTO @ VALUES (N'REALLY-75', '2026-02-10');
INSERT INTO @ VALUES (N'RELLY-54', '2025-12-01');
INSERT INTO @ VALUES (N'REALLY-76', '2025-12-11');
INSERT INTO @ VALUES (N'REALLY-77', '2026-03-09');
INSERT INTO @ VALUES (N'REALLY-78', NULL);
INSERT INTO @ VALUES (N'REALLY-79', NULL);
INSERT INTO @ VALUES (N'REALLY-80', NULL);
INSERT INTO @ VALUES (N'REALLY-81', NULL);
INSERT INTO @ VALUES (N'REALLY-82', NULL);
INSERT INTO @ VALUES (N'REALLY-83', NULL);
INSERT INTO @ VALUES (N'REALLY-84', NULL);
INSERT INTO @ VALUES (N'REALLY-85', NULL);
INSERT INTO @ VALUES (N'REALLY-86', NULL);
INSERT INTO @ VALUES (N'REALLY-87', '2026-05-20');
INSERT INTO @ VALUES (N'REALLY-88', NULL);
UPDATE target SET target.[] = source.[]
FROM [dbo].[_设备工位点检表] target INNER JOIN @ source ON target.[] = source.[];
SELECT COUNT(*) AS [] FROM [dbo].[_设备工位点检表];
GO

View File

@@ -0,0 +1,120 @@
USE [YL_MESDB]
GO
ALTER PROCEDURE [dbo].[_设备信息_增加]
@ nvarchar(100) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(500) = NULL,
@使 nvarchar(100) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ decimal(18, 4) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(10) = NULL,
@ decimal(18, 4) = NULL,
@ nvarchar(10) = NULL,
@ nvarchar(50) = NULL
AS
BEGIN
SET NOCOUNT ON;
IF ISNULL(@, N'') = N''
BEGIN
SELECT '0' AS result, N'公司编码不能为空' AS message;
RETURN;
END
INSERT INTO [dbo].[_设备工位点检表] (
[],
[],
[],
[],
[],
[使],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[]
)
VALUES (
@,
@,
@,
@,
@,
@使,
TRY_CONVERT(date, NULLIF(@, N'')),
@,
@,
@,
@,
@,
@,
@,
@,
@,
TRY_CONVERT(date, NULLIF(@, N''))
);
SELECT '1' AS result;
END
GO
ALTER PROCEDURE [dbo].[_设备信息_编辑]
@ int = NULL,
@ nvarchar(100) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(500) = NULL,
@使 nvarchar(100) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ decimal(18, 4) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(10) = NULL,
@ decimal(18, 4) = NULL,
@ nvarchar(10) = NULL,
@ nvarchar(50) = NULL
AS
BEGIN
SET NOCOUNT ON;
UPDATE [dbo].[_设备工位点检表]
SET
[] = @,
[] = @,
[] = @,
[] = @,
[使] = @使,
[] = TRY_CONVERT(date, NULLIF(@, N'')),
[] = @,
[] = @,
[] = @,
[] = @,
[] = @,
[] = @,
[] = @,
[] = @,
[] = @,
[] = TRY_CONVERT(date, NULLIF(@, N''))
WHERE [] = @;
SELECT '1' AS result;
END
GO

View File

@@ -0,0 +1,208 @@
CREATE PROCEDURE [dbo].[_作业者工时_查询]
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(100) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ DATE = NULL,
@ DATE = NULL
AS
BEGIN
SET NOCOUNT ON;
;WITH AS (
SELECT
LTRIM(RTRIM(Personnel_Name)) AS Personnel_Name,
MAX(NULLIF(LTRIM(RTRIM()), '')) AS
FROM [YL_MESDB].[dbo].[_人员信息]
WHERE Personnel_Name IS NOT NULL
GROUP BY LTRIM(RTRIM(Personnel_Name))
),
AS (
SELECT
v.*,
ISNULL(p., '未分类') AS ,
CASE
WHEN v. IN ('报工', '辅助结束') AND ISNULL(v., 0) > 0 THEN ISNULL(v., 0)
WHEN v. IN ('报工', '辅助结束') AND ISNULL(v., 0) > 0 AND ISNULL(v., 0) = 0 THEN ISNULL(v., 0)
WHEN v. LIKE '%加班%' AND ISNULL(v., 0) > 0 THEN ISNULL(v., 0)
WHEN v. = '开始加工' AND ISNULL(v., 0) > 0 THEN ISNULL(v., 0)
WHEN v. = '异常' THEN -ISNULL(v., 0)
ELSE 0
END AS
FROM [dbo].[View_生产工时视图全部] v
LEFT JOIN p ON LTRIM(RTRIM(v.)) = p.Personnel_Name
),
AS (
SELECT *
FROM
WHERE (@ IS NULL OR @ = '' OR >= @)
AND (@ IS NULL OR @ = '' OR <= @)
AND IS NOT NULL AND != ''
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR = @)
AND ISNULL(, 0) != -1
),
TaskStart报工数量 AS (
SELECT
TaskAID,
CONVERT(VARCHAR(19), , 120) AS ,
MAX(CASE
WHEN NOT IN ('异常') THEN ISNULL(, 0)
WHEN = '异常' THEN -ISNULL(, 0)
ELSE 0
END) AS
FROM [dbo].[View_生产工时视图全部]
WHERE = 6
GROUP BY TaskAID, CONVERT(VARCHAR(19), , 120)
),
AS (
SELECT
b.,
CONVERT(VARCHAR(10), b., 120) AS ,
b.TaskAID,
b. AS ,
b.,
b.,
b.,
b.,
b.,
b.,
b. AS ,
ISNULL(q., CASE
WHEN b. NOT IN ('异常') THEN ISNULL(b., 0)
WHEN b. = '异常' THEN -ISNULL(b., 0)
ELSE 0
END) AS ,
CONVERT(VARCHAR(19), b., 120) AS ,
CONVERT(VARCHAR(19), b., 120) AS ,
CAST(b. / 60.0 / 60.0 AS DECIMAL(10,2)) AS ,
b.,
b.,
b.
FROM b
LEFT JOIN TaskStart报工数量 q
ON q.TaskAID = b.TaskAID
AND q. = CONVERT(VARCHAR(19), b., 120)
),
AS (
SELECT , SUM() AS
FROM (
SELECT , TaskAID, , MAX() AS
FROM
WHERE TaskAID IS NOT NULL AND IS NOT NULL AND != ''
GROUP BY , TaskAID,
) x
GROUP BY
),
AS (
SELECT , , SUM() AS
FROM (
SELECT , , TaskAID, , MAX() AS
FROM
WHERE TaskAID IS NOT NULL AND IS NOT NULL AND != ''
GROUP BY , , TaskAID,
) x
GROUP BY ,
),
AS (
SELECT
,
COUNT(*) AS ,
CAST(SUM() / 60.0 / 60.0 AS DECIMAL(10,1)) AS
FROM
GROUP BY
),
AS (
SELECT
,
CONVERT(VARCHAR(10), , 120) AS ,
COUNT(*) AS ,
CAST(SUM() / 60.0 / 60.0 AS DECIMAL(10,1)) AS
FROM
GROUP BY , CONVERT(VARCHAR(10), , 120)
)
SELECT
1 AS [Level],
s. AS operator,
'' AS dateLabel,
CAST(s. AS VARCHAR(20)) AS reportCount,
CAST(ISNULL(q., 0) AS VARCHAR(20)) AS reportQty,
'' AS contractNo,
'' AS orderNo,
'' AS productCode,
'' AS productName,
'' AS processName,
CAST(NULL AS DECIMAL(19,6)) AS ,
'' AS ,
'' AS ,
'' AS startTime,
'' AS endTime,
'' AS ,
'' AS ,
'' AS ,
CAST(s. AS VARCHAR(20)) AS workHours,
'' AS TaskAID
FROM s
LEFT JOIN q ON q. = s.
UNION ALL
SELECT
2 AS [Level],
s. AS operator,
s. AS dateLabel,
CAST(s. AS VARCHAR(20)) AS reportCount,
CAST(ISNULL(q., 0) AS VARCHAR(20)) AS reportQty,
'' AS contractNo,
'' AS orderNo,
'' AS productCode,
'' AS productName,
'' AS processName,
CAST(NULL AS DECIMAL(19,6)) AS ,
'' AS ,
'' AS ,
'' AS startTime,
'' AS endTime,
'' AS ,
'' AS ,
'' AS ,
CAST(s. AS VARCHAR(20)) AS workHours,
'' AS TaskAID
FROM s
LEFT JOIN q ON q. = s. AND q. = s.
UNION ALL
SELECT
3 AS [Level],
AS operator,
AS dateLabel,
'' AS reportCount,
CAST( AS VARCHAR(20)) AS reportQty,
ISNULL(, '') AS contractNo,
ISNULL(, '') AS orderNo,
ISNULL(, '') AS productCode,
ISNULL(, '') AS productName,
ISNULL(, '') AS processName,
AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS startTime,
ISNULL(, '') AS endTime,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
CAST( AS VARCHAR(20)) AS workHours,
CAST(TaskAID AS VARCHAR(50)) AS TaskAID
FROM
ORDER BY operator, dateLabel, [Level], startTime
END

View File

@@ -0,0 +1,192 @@
CREATE PROCEDURE [dbo].[_作业者工时_查询]
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(100) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ DATE = NULL,
@ DATE = NULL
AS
BEGIN
SET NOCOUNT ON;
;WITH AS (
SELECT
LTRIM(RTRIM(Personnel_Name)) AS Personnel_Name,
MAX(NULLIF(LTRIM(RTRIM()), '')) AS
FROM [YL_MESDB].[dbo].[_人员信息]
WHERE Personnel_Name IS NOT NULL
GROUP BY LTRIM(RTRIM(Personnel_Name))
),
AS (
SELECT
v.*,
ISNULL(p., '未分类') AS ,
CASE
WHEN v. IN ('报工', '辅助结束') AND ISNULL(v., 0) > 0 THEN ISNULL(v., 0)
WHEN v. IN ('报工', '辅助结束') AND ISNULL(v., 0) > 0 AND ISNULL(v., 0) = 0 THEN ISNULL(v., 0)
WHEN v. LIKE '%加班%' AND ISNULL(v., 0) > 0 THEN ISNULL(v., 0)
WHEN v. = '开始加工' AND ISNULL(v., 0) > 0 THEN ISNULL(v., 0)
WHEN v. = '异常' THEN -ISNULL(v., 0)
ELSE 0
END AS
FROM [dbo].[View_生产工时视图全部] v
LEFT JOIN p ON LTRIM(RTRIM(v.)) = p.Personnel_Name
),
AS (
SELECT
,
COUNT(*) AS ,
SUM(CASE
WHEN NOT IN ('异常') THEN
WHEN = '异常' THEN -
ELSE 0
END) AS ,
CAST(SUM() / 60.0 / 60.0 AS DECIMAL(10,1)) AS
FROM
WHERE (@ IS NULL OR @ = '' OR >= @)
AND (@ IS NULL OR @ = '' OR <= @)
AND IS NOT NULL AND != ''
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR = @)
AND ISNULL(, 0) != -1
GROUP BY
),
AS (
SELECT
,
CONVERT(VARCHAR(10), , 120) AS ,
COUNT(*) AS ,
SUM(CASE
WHEN NOT IN ('异常') THEN
WHEN = '异常' THEN -
ELSE 0
END) AS ,
CAST(SUM() / 60.0 / 60.0 AS DECIMAL(10,1)) AS
FROM
WHERE (@ IS NULL OR @ = '' OR >= @)
AND (@ IS NULL OR @ = '' OR <= @)
AND IS NOT NULL AND != ''
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR = @)
AND ISNULL(, 0) != -1
GROUP BY , CONVERT(VARCHAR(10), , 120)
),
AS (
SELECT
,
CONVERT(VARCHAR(10), , 120) AS ,
AS ,
,
,
,
,
,
,
AS ,
CASE
WHEN NOT IN ('异常') THEN
WHEN = '异常' THEN -
ELSE 0
END AS ,
CONVERT(VARCHAR(19), , 120) AS ,
CONVERT(VARCHAR(19), , 120) AS ,
CAST( / 60.0 / 60.0 AS DECIMAL(10,2)) AS ,
,
,
FROM
WHERE (@ IS NULL OR @ = '' OR >= @)
AND (@ IS NULL OR @ = '' OR <= @)
AND IS NOT NULL AND != ''
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR = @)
AND ISNULL(, 0) != -1
)
SELECT
1 AS [Level],
AS operator,
'' AS dateLabel,
CAST( AS VARCHAR(20)) AS reportCount,
CAST( AS VARCHAR(20)) AS reportQty,
'' AS contractNo,
'' AS orderNo,
'' AS productCode,
'' AS productName,
'' AS processName,
CAST(NULL AS DECIMAL(19,6)) AS ,
'' AS ,
'' AS ,
'' AS startTime,
'' AS endTime,
'' AS ,
'' AS ,
'' AS ,
CAST( AS VARCHAR(20)) AS workHours
FROM
UNION ALL
SELECT
2 AS [Level],
AS operator,
AS dateLabel,
CAST( AS VARCHAR(20)) AS reportCount,
CAST( AS VARCHAR(20)) AS reportQty,
'' AS contractNo,
'' AS orderNo,
'' AS productCode,
'' AS productName,
'' AS processName,
CAST(NULL AS DECIMAL(19,6)) AS ,
'' AS ,
'' AS ,
'' AS startTime,
'' AS endTime,
'' AS ,
'' AS ,
'' AS ,
CAST( AS VARCHAR(20)) AS workHours
FROM
UNION ALL
SELECT
3 AS [Level],
AS operator,
AS dateLabel,
'' AS reportCount,
CAST( AS VARCHAR(20)) AS reportQty,
ISNULL(, '') AS contractNo,
ISNULL(, '') AS orderNo,
ISNULL(, '') AS productCode,
ISNULL(, '') AS productName,
ISNULL(, '') AS processName,
AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS startTime,
ISNULL(, '') AS endTime,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
CAST( AS VARCHAR(20)) AS workHours
FROM
ORDER BY operator, dateLabel, [Level]
END

View File

@@ -0,0 +1,209 @@
CREATE PROCEDURE [dbo].[_作业者工时_查询]
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(100) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ DATE = NULL,
@ DATE = NULL
AS
BEGIN
SET NOCOUNT ON;
;WITH AS (
SELECT
LTRIM(RTRIM(Personnel_Name)) AS Personnel_Name,
MAX(NULLIF(LTRIM(RTRIM()), '')) AS
FROM [YL_MESDB].[dbo].[_人员信息]
WHERE Personnel_Name IS NOT NULL
GROUP BY LTRIM(RTRIM(Personnel_Name))
),
AS (
SELECT
v.*,
ISNULL(p., '未分类') AS ,
CASE
WHEN v. IN ('报工', '辅助结束') AND ISNULL(v., 0) > 0 THEN ISNULL(v., 0)
WHEN v. IN ('报工', '辅助结束') AND ISNULL(v., 0) > 0 AND ISNULL(v., 0) = 0 THEN ISNULL(v., 0)
WHEN v. LIKE '%加班%' AND ISNULL(v., 0) > 0 THEN ISNULL(v., 0)
WHEN v. = '开始加工' AND ISNULL(v., 0) > 0 THEN ISNULL(v., 0)
WHEN v. = '异常' THEN -ISNULL(v., 0)
ELSE 0
END AS
FROM [dbo].[View_生产工时视图全部] v
LEFT JOIN p ON LTRIM(RTRIM(v.)) = p.Personnel_Name
),
AS (
SELECT *
FROM
WHERE (@ IS NULL OR @ = '' OR >= @)
AND (@ IS NULL OR @ = '' OR <= @)
AND IS NOT NULL AND != ''
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR = @)
AND ISNULL(, 0) != -1
),
TaskStart报工数量 AS (
SELECT
TaskAID,
CONVERT(VARCHAR(19), , 120) AS ,
MAX(CASE
WHEN NOT IN ('异常') THEN ISNULL(, 0)
WHEN = '异常' THEN -ISNULL(, 0)
ELSE 0
END) AS
FROM [dbo].[View_生产工时视图全部]
where = 6
GROUP BY TaskAID, CONVERT(VARCHAR(19), , 120)
),
AS (
SELECT
b.,
CONVERT(VARCHAR(10), b., 120) AS ,
b.TaskAID,
b. AS ,
b.,
b.,
b.,
b.,
b.,
b.,
b. AS ,
ISNULL(q., CASE
WHEN b. NOT IN ('异常') THEN ISNULL(b., 0)
WHEN b. = '异常' THEN -ISNULL(b., 0)
ELSE 0
END) AS ,
CONVERT(VARCHAR(19), b., 120) AS ,
CONVERT(VARCHAR(19), b., 120) AS ,
CAST(b. / 60.0 / 60.0 AS DECIMAL(10,2)) AS ,
b.,
b.,
b.
FROM b
LEFT JOIN TaskStart报工数量 q
ON q.TaskAID = b.TaskAID
AND q. = CONVERT(VARCHAR(19), b., 120)
),
AS (
SELECT , SUM() AS
FROM (
SELECT , TaskAID, , MAX() AS
FROM
WHERE TaskAID IS NOT NULL AND IS NOT NULL AND != ''
GROUP BY , TaskAID,
) x
GROUP BY
),
AS (
SELECT , , SUM() AS
FROM (
SELECT , , TaskAID, , MAX() AS
FROM
WHERE TaskAID IS NOT NULL AND IS NOT NULL AND != ''
GROUP BY , , TaskAID,
) x
GROUP BY ,
),
AS (
SELECT
,
COUNT(*) AS ,
CAST(SUM() / 60.0 / 60.0 AS DECIMAL(10,1)) AS
FROM
GROUP BY
),
AS (
SELECT
,
CONVERT(VARCHAR(10), , 120) AS ,
COUNT(*) AS ,
CAST(SUM() / 60.0 / 60.0 AS DECIMAL(10,1)) AS
FROM
GROUP BY , CONVERT(VARCHAR(10), , 120)
)
SELECT
1 AS [Level],
s. AS operator,
'' AS dateLabel,
CAST(s. AS VARCHAR(20)) AS reportCount,
CAST(ISNULL(q., 0) AS VARCHAR(20)) AS reportQty,
'' AS contractNo,
'' AS orderNo,
'' AS productCode,
'' AS productName,
'' AS processName,
CAST(NULL AS DECIMAL(19,6)) AS ,
'' AS ,
'' AS ,
'' AS startTime,
'' AS endTime,
'' AS ,
'' AS ,
'' AS ,
CAST(s. AS VARCHAR(20)) AS workHours,
'' AS TaskAID
FROM s
LEFT JOIN q ON q. = s.
UNION ALL
SELECT
2 AS [Level],
s. AS operator,
s. AS dateLabel,
CAST(s. AS VARCHAR(20)) AS reportCount,
CAST(ISNULL(q., 0) AS VARCHAR(20)) AS reportQty,
'' AS contractNo,
'' AS orderNo,
'' AS productCode,
'' AS productName,
'' AS processName,
CAST(NULL AS DECIMAL(19,6)) AS ,
'' AS ,
'' AS ,
'' AS startTime,
'' AS endTime,
'' AS ,
'' AS ,
'' AS ,
CAST(s. AS VARCHAR(20)) AS workHours,
'' AS TaskAID
FROM s
LEFT JOIN q ON q. = s. AND q. = s.
UNION ALL
SELECT
3 AS [Level],
AS operator,
AS dateLabel,
'' AS reportCount,
CAST( AS VARCHAR(20)) AS reportQty,
ISNULL(, '') AS contractNo,
ISNULL(, '') AS orderNo,
ISNULL(, '') AS productCode,
ISNULL(, '') AS productName,
ISNULL(, '') AS processName,
AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS startTime,
ISNULL(, '') AS endTime,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
CAST( AS VARCHAR(20)) AS workHours,
CAST(TaskAID AS VARCHAR(50)) AS TaskAID
FROM
ORDER BY operator, dateLabel, [Level], startTime
END

View File

@@ -0,0 +1,209 @@
CREATE PROCEDURE [dbo].[_作业者工时_查询]
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(100) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ DATE = NULL,
@ DATE = NULL
AS
BEGIN
SET NOCOUNT ON;
;WITH AS (
SELECT
LTRIM(RTRIM(Personnel_Name)) AS Personnel_Name,
MAX(NULLIF(LTRIM(RTRIM()), '')) AS
FROM [YL_MESDB].[dbo].[_人员信息]
WHERE Personnel_Name IS NOT NULL
GROUP BY LTRIM(RTRIM(Personnel_Name))
),
AS (
SELECT
v.*,
ISNULL(p., '未分类') AS ,
CASE
WHEN v. IN ('报工', '辅助结束') AND ISNULL(v., 0) > 0 THEN ISNULL(v., 0)
WHEN v. IN ('报工', '辅助结束') AND ISNULL(v., 0) > 0 AND ISNULL(v., 0) = 0 THEN ISNULL(v., 0)
WHEN v. LIKE '%加班%' AND ISNULL(v., 0) > 0 THEN ISNULL(v., 0)
WHEN v. = '开始加工' AND ISNULL(v., 0) > 0 THEN ISNULL(v., 0)
WHEN v. = '异常' THEN -ISNULL(v., 0)
ELSE 0
END AS
FROM [dbo].[View_生产工时视图全部] v
LEFT JOIN p ON LTRIM(RTRIM(v.)) = p.Personnel_Name
),
AS (
SELECT *
FROM
WHERE (@ IS NULL OR @ = '' OR >= @)
AND (@ IS NULL OR @ = '' OR <= @)
AND IS NOT NULL AND != ''
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR = @)
AND ISNULL(, 0) != -1
),
TaskStart报工数量 AS (
SELECT
TaskAID,
CONVERT(VARCHAR(19), , 120) AS ,
MAX(CASE
WHEN NOT IN ('异常') THEN ISNULL(, 0)
WHEN = '异常' THEN -ISNULL(, 0)
ELSE 0
END) AS
FROM
WHERE TaskAID IS NOT NULL
AND IS NOT NULL
GROUP BY TaskAID, CONVERT(VARCHAR(19), , 120)
),
AS (
SELECT
b.,
CONVERT(VARCHAR(10), b., 120) AS ,
b.TaskAID,
b. AS ,
b.,
b.,
b.,
b.,
b.,
b.,
b. AS ,
ISNULL(q., CASE
WHEN b. NOT IN ('异常') THEN ISNULL(b., 0)
WHEN b. = '异常' THEN -ISNULL(b., 0)
ELSE 0
END) AS ,
CONVERT(VARCHAR(19), b., 120) AS ,
CONVERT(VARCHAR(19), b., 120) AS ,
CAST(b. / 60.0 / 60.0 AS DECIMAL(10,2)) AS ,
b.,
b.,
b.
FROM b
LEFT JOIN TaskStart报工数量 q
ON q.TaskAID = b.TaskAID
AND q. = CONVERT(VARCHAR(19), b., 120)
),
AS (
SELECT , SUM() AS
FROM (
SELECT , TaskAID, , MAX() AS
FROM
WHERE TaskAID IS NOT NULL AND IS NOT NULL AND != ''
GROUP BY , TaskAID,
) x
GROUP BY
),
AS (
SELECT , , SUM() AS
FROM (
SELECT , , TaskAID, , MAX() AS
FROM
WHERE TaskAID IS NOT NULL AND IS NOT NULL AND != ''
GROUP BY , , TaskAID,
) x
GROUP BY ,
),
AS (
SELECT
,
COUNT(*) AS ,
CAST(SUM() / 60.0 / 60.0 AS DECIMAL(10,1)) AS
FROM
GROUP BY
),
AS (
SELECT
,
CONVERT(VARCHAR(10), , 120) AS ,
COUNT(*) AS ,
CAST(SUM() / 60.0 / 60.0 AS DECIMAL(10,1)) AS
FROM
GROUP BY , CONVERT(VARCHAR(10), , 120)
)
SELECT
1 AS [Level],
s. AS operator,
'' AS dateLabel,
CAST(s. AS VARCHAR(20)) AS reportCount,
CAST(ISNULL(q., 0) AS VARCHAR(20)) AS reportQty,
'' AS contractNo,
'' AS orderNo,
'' AS productCode,
'' AS productName,
'' AS processName,
CAST(NULL AS DECIMAL(19,6)) AS ,
'' AS ,
'' AS ,
'' AS startTime,
'' AS endTime,
'' AS ,
'' AS ,
'' AS ,
CAST(s. AS VARCHAR(20)) AS workHours,
'' AS TaskAID
FROM s
LEFT JOIN q ON q. = s.
UNION ALL
SELECT
2 AS [Level],
s. AS operator,
s. AS dateLabel,
CAST(s. AS VARCHAR(20)) AS reportCount,
CAST(ISNULL(q., 0) AS VARCHAR(20)) AS reportQty,
'' AS contractNo,
'' AS orderNo,
'' AS productCode,
'' AS productName,
'' AS processName,
CAST(NULL AS DECIMAL(19,6)) AS ,
'' AS ,
'' AS ,
'' AS startTime,
'' AS endTime,
'' AS ,
'' AS ,
'' AS ,
CAST(s. AS VARCHAR(20)) AS workHours,
'' AS TaskAID
FROM s
LEFT JOIN q ON q. = s. AND q. = s.
UNION ALL
SELECT
3 AS [Level],
AS operator,
AS dateLabel,
'' AS reportCount,
CAST( AS VARCHAR(20)) AS reportQty,
ISNULL(, '') AS contractNo,
ISNULL(, '') AS orderNo,
ISNULL(, '') AS productCode,
ISNULL(, '') AS productName,
ISNULL(, '') AS processName,
AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS startTime,
ISNULL(, '') AS endTime,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
CAST( AS VARCHAR(20)) AS workHours,
CAST(TaskAID AS VARCHAR(50)) AS TaskAID
FROM
ORDER BY operator, dateLabel, [Level], startTime
END

View File

@@ -0,0 +1,71 @@
CREATE PROCEDURE [dbo].[_作业者工时_查询_导出]
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(100) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ DATE = NULL,
@ DATE = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT '作业者工时统计_' + REPLACE(REPLACE(REPLACE(CONVERT(NVARCHAR(19), GETDATE(), 21), ':', ''), '-', ''), ' ', '-') AS tablename, '15' AS tabletype
SELECT 256*12 AS , 256*15 AS , 256*20 AS , 256*12 AS , 256*40 AS ,
256*25 AS , 256*15 AS , 256*12 AS , 256*10 AS , 256*20 AS , 256*20 AS , 256*12 AS '工时(h)'
SELECT 0 AS , 0 AS , 0 AS , 0 AS , 0 AS ,
0 AS , 0 AS , 0 AS , 0 AS , 0 AS , 0 AS , 0 AS '工时(h)'
;WITH AS (
SELECT *
FROM [dbo].[View_生产工时视图]
WHERE (@ IS NULL OR @ = '' OR >= @)
AND (@ IS NULL OR @ = '' OR <= @)
AND IS NOT NULL AND != ''
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND ISNULL(, 0) != -1
),
TaskStart报工数量 AS (
SELECT
TaskAID,
CONVERT(VARCHAR(19), , 120) AS ,
MAX(CASE
WHEN NOT IN ('异常') THEN ISNULL(, 0)
WHEN = '异常' THEN -ISNULL(, 0)
ELSE 0
END) AS
FROM [dbo].[View_生产工时视图全部]
WHERE = 6
GROUP BY TaskAID, CONVERT(VARCHAR(19), , 120)
)
SELECT
b.,
CONVERT(VARCHAR(10), b., 120) AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
CAST(ISNULL(q., CASE
WHEN b. NOT IN ('异常') THEN ISNULL(b., 0)
WHEN b. = '异常' THEN -ISNULL(b., 0)
ELSE 0
END) AS VARCHAR(20)) AS ,
CONVERT(VARCHAR(19), b., 120) AS ,
CONVERT(VARCHAR(19), b., 120) AS ,
CAST(CAST(b. / 60.0 / 60.0 AS DECIMAL(10,2)) AS VARCHAR(20)) AS '工时(h)'
FROM b
LEFT JOIN TaskStart报工数量 q
ON q.TaskAID = b.TaskAID
AND q. = CONVERT(VARCHAR(19), b., 120)
ORDER BY b., b.
END

View File

@@ -0,0 +1,47 @@
CREATE PROCEDURE [dbo].[_作业者工时_查询_导出]
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(100) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ DATE = NULL,
@ DATE = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT '作业者工时统计_' + REPLACE(REPLACE(REPLACE(CONVERT(NVARCHAR(19), GETDATE(), 21), ':', ''), '-', ''), ' ', '-') AS tablename, '15' AS tabletype
SELECT 256*12 AS , 256*15 AS , 256*20 AS , 256*12 AS , 256*40 AS ,
256*25 AS , 256*15 AS , 256*12 AS , 256*10 AS , 256*20 AS , 256*20 AS , 256*12 AS '工时(h)'
SELECT 0 AS , 0 AS , 0 AS , 0 AS , 0 AS ,
0 AS , 0 AS , 0 AS , 0 AS , 0 AS , 0 AS , 0 AS '工时(h)'
SELECT
,
CONVERT(VARCHAR(10), , 120) AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
CASE WHEN IN ('报工', '辅助结束', '加班', '异常', '开始加工') THEN CAST( AS VARCHAR(20)) ELSE '0' END AS ,
CONVERT(VARCHAR(19), , 120) AS ,
CONVERT(VARCHAR(19), , 120) AS ,
CAST(CAST( / 60.0 / 60.0 AS DECIMAL(10,2)) AS VARCHAR(20)) AS '工时(h)'
FROM [dbo].[View_生产工时视图]
WHERE (@ IS NULL OR @ = '' OR >= @)
AND (@ IS NULL OR @ = '' OR <= @)
AND IS NOT NULL AND != ''
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND ISNULL(, 0) != -1
ORDER BY ,
END

View File

@@ -0,0 +1,70 @@
CREATE PROCEDURE [dbo].[_作业者工时_查询_导出]
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(100) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ DATE = NULL,
@ DATE = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT '作业者工时统计_' + REPLACE(REPLACE(REPLACE(CONVERT(NVARCHAR(19), GETDATE(), 21), ':', ''), '-', ''), ' ', '-') AS tablename, '15' AS tabletype
SELECT 256*12 AS , 256*15 AS , 256*20 AS , 256*12 AS , 256*40 AS ,
256*25 AS , 256*15 AS , 256*12 AS , 256*10 AS , 256*20 AS , 256*20 AS , 256*12 AS '工时(h)'
SELECT 0 AS , 0 AS , 0 AS , 0 AS , 0 AS ,
0 AS , 0 AS , 0 AS , 0 AS , 0 AS , 0 AS , 0 AS '工时(h)'
;WITH AS (
SELECT *
FROM [dbo].[View_生产工时视图]
WHERE (@ IS NULL OR @ = '' OR >= @)
AND (@ IS NULL OR @ = '' OR <= @)
AND IS NOT NULL AND != ''
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND ISNULL(, 0) != -1
),
TaskStart报工数量 AS (
SELECT
TaskAID,
CONVERT(VARCHAR(19), , 120) AS ,
MAX(CASE
WHEN NOT IN ('异常') THEN ISNULL(, 0)
WHEN = '异常' THEN -ISNULL(, 0)
ELSE 0
END) AS
FROM [dbo].[View_生产工时视图全部]
GROUP BY TaskAID, CONVERT(VARCHAR(19), , 120)
)
SELECT
b.,
CONVERT(VARCHAR(10), b., 120) AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
CAST(ISNULL(q., CASE
WHEN b. NOT IN ('异常') THEN ISNULL(b., 0)
WHEN b. = '异常' THEN -ISNULL(b., 0)
ELSE 0
END) AS VARCHAR(20)) AS ,
CONVERT(VARCHAR(19), b., 120) AS ,
CONVERT(VARCHAR(19), b., 120) AS ,
CAST(CAST(b. / 60.0 / 60.0 AS DECIMAL(10,2)) AS VARCHAR(20)) AS '工时(h)'
FROM b
LEFT JOIN TaskStart报工数量 q
ON q.TaskAID = b.TaskAID
AND q. = CONVERT(VARCHAR(19), b., 120)
ORDER BY b., b.
END

View File

@@ -0,0 +1,72 @@
CREATE PROCEDURE [dbo].[_作业者工时_查询_导出]
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(100) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ DATE = NULL,
@ DATE = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT '作业者工时统计_' + REPLACE(REPLACE(REPLACE(CONVERT(NVARCHAR(19), GETDATE(), 21), ':', ''), '-', ''), ' ', '-') AS tablename, '15' AS tabletype
SELECT 256*12 AS , 256*15 AS , 256*20 AS , 256*12 AS , 256*40 AS ,
256*25 AS , 256*15 AS , 256*12 AS , 256*10 AS , 256*20 AS , 256*20 AS , 256*12 AS '工时(h)'
SELECT 0 AS , 0 AS , 0 AS , 0 AS , 0 AS ,
0 AS , 0 AS , 0 AS , 0 AS , 0 AS , 0 AS , 0 AS '工时(h)'
;WITH AS (
SELECT *
FROM [dbo].[View_生产工时视图]
WHERE (@ IS NULL OR @ = '' OR >= @)
AND (@ IS NULL OR @ = '' OR <= @)
AND IS NOT NULL AND != ''
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND ISNULL(, 0) != -1
),
TaskStart报工数量 AS (
SELECT
TaskAID,
CONVERT(VARCHAR(19), , 120) AS ,
MAX(CASE
WHEN NOT IN ('异常') THEN ISNULL(, 0)
WHEN = '异常' THEN -ISNULL(, 0)
ELSE 0
END) AS
FROM
WHERE TaskAID IS NOT NULL
AND IS NOT NULL
GROUP BY TaskAID, CONVERT(VARCHAR(19), , 120)
)
SELECT
b.,
CONVERT(VARCHAR(10), b., 120) AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
CAST(ISNULL(q., CASE
WHEN b. NOT IN ('异常') THEN ISNULL(b., 0)
WHEN b. = '异常' THEN -ISNULL(b., 0)
ELSE 0
END) AS VARCHAR(20)) AS ,
CONVERT(VARCHAR(19), b., 120) AS ,
CONVERT(VARCHAR(19), b., 120) AS ,
CAST(CAST(b. / 60.0 / 60.0 AS DECIMAL(10,2)) AS VARCHAR(20)) AS '工时(h)'
FROM b
LEFT JOIN TaskStart报工数量 q
ON q.TaskAID = b.TaskAID
AND q. = CONVERT(VARCHAR(19), b., 120)
ORDER BY b., b.
END

View File

@@ -0,0 +1,298 @@
/*
过程异常管控并行审批调整
目标:
1. sp_创建流程_简化版 支持前端传入多个审批人审批人ID/审批人姓名使用英文逗号分隔。
2. 多个审批人写入同一个步骤序号的多个 processing 节点,所有审批人可同时看到待办。
3. sp_获取待处理任务 兼容同一步骤多行节点也兼容旧过程已写入的逗号分隔审批人ID。
4. sp_处理审批 中任意一个审批人同意后,当前流程直接完成,并关闭同一步骤其他待处理节点。
说明:本脚本仅定义存储过程,不插入业务数据。
*/
CREATE OR ALTER PROCEDURE [dbo].[sp_创建流程_简化版]
@ NVARCHAR(200),
@ NVARCHAR(MAX),
@ NVARCHAR(20) = N'normal',
@ID NVARCHAR(100),
@ NVARCHAR(100),
@ID NVARCHAR(MAX),
@ NVARCHAR(MAX),
@ID INT = 0,
@ NVARCHAR(100) = N'',
@ NVARCHAR(100) = N'',
@ NVARCHAR(100) = N'',
@ NVARCHAR(100) = N''
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ INT = 0;
DECLARE @ NVARCHAR(500) = N'';
BEGIN TRY
BEGIN TRANSACTION;
DECLARE @IDXml XML;
DECLARE @Xml XML;
SET @IDXml = CAST(
N'<i>' +
REPLACE(REPLACE(REPLACE(REPLACE(ISNULL(@ID, N''), N'&', N'&amp;'), N'<', N'&lt;'), N'>', N'&gt;'), N',', N'</i><i>') +
N'</i>' AS XML
);
SET @Xml = CAST(
N'<i>' +
REPLACE(REPLACE(REPLACE(REPLACE(ISNULL(@, N''), N'&', N'&amp;'), N'<', N'&lt;'), N'>', N'&gt;'), N',', N'</i><i>') +
N'</i>' AS XML
);
DECLARE @ TABLE (
INT IDENTITY(1, 1) PRIMARY KEY,
ID NVARCHAR(100),
NVARCHAR(100)
);
DECLARE @ID表 TABLE (
INT IDENTITY(1, 1) PRIMARY KEY,
ID NVARCHAR(100)
);
DECLARE @ TABLE (
INT IDENTITY(1, 1) PRIMARY KEY,
NVARCHAR(100)
);
INSERT INTO @ID表 (ID)
SELECT NULLIF(LTRIM(RTRIM(T.C.value(N'.', N'NVARCHAR(100)'))), N'')
FROM @IDXml.nodes(N'/i') AS T(C);
INSERT INTO @ ()
SELECT NULLIF(LTRIM(RTRIM(T.C.value(N'.', N'NVARCHAR(100)'))), N'')
FROM @Xml.nodes(N'/i') AS T(C);
INSERT INTO @ (ID, )
SELECT I.ID, ISNULL(N., I.ID)
FROM @ID表 I
LEFT JOIN @ N ON N. = I.
WHERE I.ID IS NOT NULL;
IF NOT EXISTS (SELECT 1 FROM @)
BEGIN
INSERT INTO @ (ID, )
VALUES (@ID, @);
END;
INSERT INTO [dbo].[] (
,
,
,
,
ID,
,
,
,
,
,
,
,
,
,
)
VALUES (
@,
@,
ISNULL(NULLIF(@, N''), N'normal'),
N'processing',
@ID,
@,
N'异常审批',
1,
1,
ISNULL(@, N''),
ISNULL(@, N''),
ISNULL(@, N''),
ISNULL(@, N''),
GETDATE(),
GETDATE()
);
SET @ID = SCOPE_IDENTITY();
INSERT INTO [dbo].[] (
ID,
,
ID,
,
,
,
)
SELECT
@ID,
N'异常审批',
ID,
,
1,
N'processing',
0
FROM @;
SET @ = 1;
SET @ = N'流程创建成功流程ID: ' + CAST(@ID AS NVARCHAR(20));
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
SET @ = 0;
SET @ = N'错误: ' + ERROR_MESSAGE();
END CATCH;
SELECT @ AS , @ AS , @ID AS ID;
END;
GO
CREATE OR ALTER PROCEDURE [dbo].[sp_获取待处理任务]
@ID NVARCHAR(100)
AS
BEGIN
SET NOCOUNT ON;
SELECT
p.ID,
p.,
p.,
p.,
p.,
p. AS ,
p. AS ,
p.,
p.,
p.,
p.,
pn.ID,
pn. AS ,
pn.
FROM [dbo].[] pn
INNER JOIN [dbo].[] p ON p.ID = pn.ID
WHERE pn. = N'processing'
AND p. = N'processing'
AND (
pn.ID = @ID
OR CHARINDEX(N',' + @ID + N',', N',' + REPLACE(ISNULL(pn.ID, N''), N'', N',') + N',') > 0
)
ORDER BY p. DESC, p. DESC;
END;
GO
CREATE OR ALTER PROCEDURE [dbo].[sp_处理审批]
@ID INT,
@ID INT,
@ID NVARCHAR(100),
@ NVARCHAR(100),
@ NVARCHAR(20),
@ NVARCHAR(MAX) = N'',
@ BIT = 0
AS
BEGIN
SET NOCOUNT ON;
SET @ = 0;
BEGIN TRY
BEGIN TRANSACTION;
DECLARE @ INT;
SELECT @ =
FROM [dbo].[]
WHERE ID = @ID
AND ID = @ID
AND = N'processing';
IF @ IS NULL
BEGIN
RAISERROR(N'待处理节点不存在或已处理。', 16, 1);
END;
INSERT INTO [dbo].[] (
ID,
ID,
ID,
,
,
)
VALUES (
@ID,
@ID,
@ID,
@,
@,
ISNULL(@, N'')
);
IF @ = N'approved'
BEGIN
UPDATE [dbo].[]
SET = N'approved'
WHERE ID = @ID
AND = @
AND = N'processing';
UPDATE [dbo].[]
SET = N'completed',
= N'已完成',
= GETDATE()
WHERE ID = @ID;
IF COL_LENGTH(N'dbo.流程表', N'完成人') IS NOT NULL
BEGIN
EXEC sp_executesql
N'UPDATE [dbo].[流程表] SET 完成人 = @p审批人姓名 WHERE 流程ID = @p流程ID',
N'@p审批人姓名 NVARCHAR(100), @p流程ID INT',
@p审批人姓名 = @,
@p流程ID = @ID;
END;
IF COL_LENGTH(N'dbo.流程表', N'完成时间') IS NOT NULL
BEGIN
EXEC sp_executesql
N'UPDATE [dbo].[流程表] SET 完成时间 = GETDATE() WHERE 流程ID = @p流程ID',
N'@p流程ID INT',
@p流程ID = @ID;
END;
END
ELSE IF @ = N'rejected'
BEGIN
UPDATE [dbo].[]
SET = N'rejected'
WHERE ID = @ID
AND = @
AND = N'processing';
UPDATE [dbo].[]
SET = N'rejected',
= N'已拒绝',
= GETDATE()
WHERE ID = @ID;
END
ELSE
BEGIN
UPDATE [dbo].[]
SET = @
WHERE ID = @ID;
END;
SET @ = 1;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
SET @ = 0;
THROW;
END CATCH;
SELECT @ AS ;
END;
GO

View File

@@ -0,0 +1,190 @@
USE [YL_MESDB]
GO
IF COL_LENGTH(N'dbo.基础数据_设备工位点检表', N'公司编码') IS NULL
ALTER TABLE [dbo].[_设备工位点检表] ADD [] nvarchar(100) NULL
GO
IF COL_LENGTH(N'dbo.基础数据_设备工位点检表', N'设备信息') IS NULL
ALTER TABLE [dbo].[_设备工位点检表] ADD [] nvarchar(500) NULL
GO
IF COL_LENGTH(N'dbo.基础数据_设备工位点检表', N'使用部门') IS NULL
ALTER TABLE [dbo].[_设备工位点检表] ADD [使] nvarchar(100) NULL
GO
IF COL_LENGTH(N'dbo.基础数据_设备工位点检表', N'入账日期') IS NULL
ALTER TABLE [dbo].[_设备工位点检表] ADD [] date NULL
GO
IF COL_LENGTH(N'dbo.基础数据_设备工位点检表', N'单位') IS NULL
ALTER TABLE [dbo].[_设备工位点检表] ADD [] nvarchar(50) NULL
GO
IF COL_LENGTH(N'dbo.基础数据_设备工位点检表', N'数量') IS NULL
ALTER TABLE [dbo].[_设备工位点检表] ADD [] decimal(18, 4) NULL
GO
IF COL_LENGTH(N'dbo.基础数据_设备工位点检表', N'状态') IS NULL
ALTER TABLE [dbo].[_设备工位点检表] ADD [] nvarchar(50) NULL
GO
IF COL_LENGTH(N'dbo.基础数据_设备工位点检表', N'维修记录') IS NULL
ALTER TABLE [dbo].[_设备工位点检表] ADD [] nvarchar(1000) NULL
GO
IF COL_LENGTH(N'dbo.基础数据_设备工位点检表', N'维保记录') IS NULL
ALTER TABLE [dbo].[_设备工位点检表] ADD [] nvarchar(1000) NULL
GO
IF COL_LENGTH(N'dbo.基础数据_设备工位点检表', N'工位绑定') IS NULL
ALTER TABLE [dbo].[_设备工位点检表] ADD [] nvarchar(1000) NULL
GO
IF COL_LENGTH(N'dbo.基础数据_设备工位点检表', N'主要设备') IS NULL
ALTER TABLE [dbo].[_设备工位点检表] ADD [] nvarchar(10) NULL
GO
IF COL_LENGTH(N'dbo.基础数据_设备工位点检表', N'设备标准开机工时') IS NULL
ALTER TABLE [dbo].[_设备工位点检表] ADD [] decimal(18, 4) NULL
GO
IF COL_LENGTH(N'dbo.基础数据_设备工位点检表', N'特种设备') IS NULL
ALTER TABLE [dbo].[_设备工位点检表] ADD [] nvarchar(10) NULL
GO
IF COL_LENGTH(N'dbo.基础数据_设备工位点检表', N'证书有效期至') IS NULL
ALTER TABLE [dbo].[_设备工位点检表] ADD [] date NULL
GO
ALTER PROCEDURE [dbo].[_设备信息_查询]
@_check bit = NULL,
@ nvarchar(50) = NULL,
@_check bit = NULL,
@ int = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT
a.*,
d.[] AS []
FROM [dbo].[_设备工位点检表] a
LEFT JOIN [dbo].[YL_基础表_数据字典] d ON a.[] = d.[AID]
WHERE (@_check IS NULL OR @_check = 0 OR a.[] LIKE N'%' + ISNULL(@, N'') + N'%')
AND (@_check IS NULL OR @_check = 0 OR a.[] = CONVERT(nvarchar(50), @))
ORDER BY
CASE
WHEN a.[] IS NOT NULL AND a.[] < CONVERT(date, GETDATE()) THEN 0
WHEN a.[] IS NOT NULL AND a.[] <= DATEADD(day, 30, CONVERT(date, GETDATE())) THEN 1
ELSE 2
END,
a.[],
a.[] DESC;
END
GO
ALTER PROCEDURE [dbo].[_设备信息_增加]
@ nvarchar(100) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(500) = NULL,
@使 nvarchar(100) = NULL,
@ date = NULL,
@ nvarchar(50) = NULL,
@ decimal(18, 4) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(10) = NULL,
@ decimal(18, 4) = NULL,
@ nvarchar(10) = NULL,
@ date = NULL
AS
BEGIN
SET NOCOUNT ON;
IF ISNULL(@, N'') = N''
BEGIN
SELECT '0' AS result, N'公司编码不能为空' AS message;
RETURN;
END
INSERT INTO [dbo].[_设备工位点检表] (
[],
[],
[],
[],
[],
[使],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[]
)
VALUES (
@,
@,
@,
@,
@,
@使,
@,
@,
@,
@,
@,
@,
@,
@,
@,
@,
@
);
SELECT '1' AS result;
END
GO
ALTER PROCEDURE [dbo].[_设备信息_编辑]
@ int = NULL,
@ nvarchar(100) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(500) = NULL,
@使 nvarchar(100) = NULL,
@ date = NULL,
@ nvarchar(50) = NULL,
@ decimal(18, 4) = NULL,
@ nvarchar(50) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(1000) = NULL,
@ nvarchar(10) = NULL,
@ decimal(18, 4) = NULL,
@ nvarchar(10) = NULL,
@ date = NULL
AS
BEGIN
SET NOCOUNT ON;
UPDATE [dbo].[_设备工位点检表]
SET
[] = @,
[] = @,
[] = @,
[] = @,
[使] = @使,
[] = @,
[] = @,
[] = @,
[] = @,
[] = @,
[] = @,
[] = @,
[] = @,
[] = @,
[] = @,
[] = @
WHERE [] = @;
SELECT '1' AS result;
END
GO

View File

@@ -0,0 +1,290 @@
USE [YL_MESDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
ALTER PROCEDURE [dbo].[_作业者工时_查询]
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(100) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ DATE = NULL,
@ DATE = NULL
AS
BEGIN
SET NOCOUNT ON;
;WITH AS (
SELECT
LTRIM(RTRIM(Personnel_Name)) AS Personnel_Name,
MAX(NULLIF(LTRIM(RTRIM()), '')) AS
FROM [YL_MESDB].[dbo].[_人员信息]
WHERE Personnel_Name IS NOT NULL
GROUP BY LTRIM(RTRIM(Personnel_Name))
),
AS (
SELECT
v.*,
ISNULL(p., '未分类') AS ,
CASE
WHEN v. IN ('报工', '辅助结束') AND ISNULL(v., 0) > 0 THEN ISNULL(v., 0)
WHEN v. IN ('报工', '辅助结束') AND ISNULL(v., 0) > 0 AND ISNULL(v., 0) = 0 THEN ISNULL(v., 0)
WHEN v. LIKE '%加班%' AND ISNULL(v., 0) > 0 THEN ISNULL(v., 0)
WHEN v. = '开始加工' AND ISNULL(v., 0) > 0 THEN ISNULL(v., 0)
WHEN v. = '异常' THEN -ISNULL(v., 0)
ELSE 0
END AS
FROM [dbo].[View_生产工时视图全部] v
LEFT JOIN p ON LTRIM(RTRIM(v.)) = p.Personnel_Name
),
AS (
SELECT *
FROM
WHERE (@ IS NULL OR @ = '' OR >= @)
AND (@ IS NULL OR @ = '' OR <= @)
AND IS NOT NULL AND != ''
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR = @)
AND ISNULL(, 0) != -1
),
TaskStart报工数量 AS (
SELECT
TaskAID,
CONVERT(VARCHAR(19), , 120) AS ,
MAX(CASE
WHEN NOT IN ('异常') THEN ISNULL(, 0)
WHEN = '异常' THEN -ISNULL(, 0)
ELSE 0
END) AS
FROM [dbo].[View_生产工时视图全部]
GROUP BY TaskAID, CONVERT(VARCHAR(19), , 120)
),
AS (
SELECT
b.,
CONVERT(VARCHAR(10), b., 120) AS ,
b.TaskAID,
b. AS ,
b.,
b.,
b.,
b.,
b.,
b.,
b. AS ,
CASE
WHEN ISNULL(b., '') LIKE '%装配%' THEN 0
ELSE ISNULL(q., CASE
WHEN b. NOT IN ('异常') THEN ISNULL(b., 0)
WHEN b. = '异常' THEN -ISNULL(b., 0)
ELSE 0
END)
END AS ,
CONVERT(VARCHAR(19), b., 120) AS ,
CONVERT(VARCHAR(19), b., 120) AS ,
CAST(b. / 60.0 / 60.0 AS DECIMAL(10,2)) AS ,
b.,
b.,
b.
FROM b
LEFT JOIN TaskStart报工数量 q
ON q.TaskAID = b.TaskAID
AND q. = CONVERT(VARCHAR(19), b., 120)
),
AS (
SELECT , SUM() AS
FROM (
SELECT , TaskAID, , MAX() AS
FROM
WHERE TaskAID IS NOT NULL AND IS NOT NULL AND != ''
GROUP BY , TaskAID,
) x
GROUP BY
),
AS (
SELECT , , SUM() AS
FROM (
SELECT , , TaskAID, , MAX() AS
FROM
WHERE TaskAID IS NOT NULL AND IS NOT NULL AND != ''
GROUP BY , , TaskAID,
) x
GROUP BY ,
),
AS (
SELECT
,
COUNT(*) AS ,
CAST(SUM() / 60.0 / 60.0 AS DECIMAL(10,1)) AS
FROM
GROUP BY
),
AS (
SELECT
,
CONVERT(VARCHAR(10), , 120) AS ,
COUNT(*) AS ,
CAST(SUM() / 60.0 / 60.0 AS DECIMAL(10,1)) AS
FROM
GROUP BY , CONVERT(VARCHAR(10), , 120)
)
SELECT
1 AS [Level],
s. AS operator,
'' AS dateLabel,
CAST(s. AS VARCHAR(20)) AS reportCount,
CAST(ISNULL(q., 0) AS VARCHAR(20)) AS reportQty,
'' AS contractNo,
'' AS orderNo,
'' AS productCode,
'' AS productName,
'' AS processName,
CAST(NULL AS DECIMAL(19,6)) AS ,
'' AS ,
'' AS ,
'' AS startTime,
'' AS endTime,
'' AS ,
'' AS ,
'' AS ,
CAST(s. AS VARCHAR(20)) AS workHours,
'' AS TaskAID
FROM s
LEFT JOIN q ON q. = s.
UNION ALL
SELECT
2 AS [Level],
s. AS operator,
s. AS dateLabel,
CAST(s. AS VARCHAR(20)) AS reportCount,
CAST(ISNULL(q., 0) AS VARCHAR(20)) AS reportQty,
'' AS contractNo,
'' AS orderNo,
'' AS productCode,
'' AS productName,
'' AS processName,
CAST(NULL AS DECIMAL(19,6)) AS ,
'' AS ,
'' AS ,
'' AS startTime,
'' AS endTime,
'' AS ,
'' AS ,
'' AS ,
CAST(s. AS VARCHAR(20)) AS workHours,
'' AS TaskAID
FROM s
LEFT JOIN q ON q. = s. AND q. = s.
UNION ALL
SELECT
3 AS [Level],
AS operator,
AS dateLabel,
'' AS reportCount,
CAST( AS VARCHAR(20)) AS reportQty,
ISNULL(, '') AS contractNo,
ISNULL(, '') AS orderNo,
ISNULL(, '') AS productCode,
ISNULL(, '') AS productName,
ISNULL(, '') AS processName,
AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS startTime,
ISNULL(, '') AS endTime,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
ISNULL(, '') AS ,
CAST( AS VARCHAR(20)) AS workHours,
CAST(TaskAID AS VARCHAR(50)) AS TaskAID
FROM
ORDER BY operator, dateLabel, [Level], startTime
END
GO
ALTER PROCEDURE [dbo].[_作业者工时_查询_导出]
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(100) = NULL,
@ NVARCHAR(50) = NULL,
@ NVARCHAR(50) = NULL,
@ DATE = NULL,
@ DATE = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT '作业者工时统计_' + REPLACE(REPLACE(REPLACE(CONVERT(NVARCHAR(19), GETDATE(), 21), ':', ''), '-', ''), ' ', '-') AS tablename, '15' AS tabletype
SELECT 256*12 AS , 256*15 AS , 256*20 AS , 256*12 AS , 256*40 AS ,
256*25 AS , 256*15 AS , 256*12 AS , 256*10 AS , 256*20 AS , 256*20 AS , 256*12 AS '工时(h)'
SELECT 0 AS , 0 AS , 0 AS , 0 AS , 0 AS ,
0 AS , 0 AS , 0 AS , 0 AS , 0 AS , 0 AS , 0 AS '工时(h)'
;WITH AS (
SELECT *
FROM [dbo].[View_生产工时视图]
WHERE (@ IS NULL OR @ = '' OR >= @)
AND (@ IS NULL OR @ = '' OR <= @)
AND IS NOT NULL AND != ''
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR LIKE '%' + @ + '%')
AND ISNULL(, 0) != -1
),
TaskStart报工数量 AS (
SELECT
TaskAID,
CONVERT(VARCHAR(19), , 120) AS ,
MAX(CASE
WHEN NOT IN ('异常') THEN ISNULL(, 0)
WHEN = '异常' THEN -ISNULL(, 0)
ELSE 0
END) AS
FROM [dbo].[View_生产工时视图全部]
GROUP BY TaskAID, CONVERT(VARCHAR(19), , 120)
)
SELECT
b.,
CONVERT(VARCHAR(10), b., 120) AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
ISNULL(b., '') AS ,
CAST(CASE
WHEN ISNULL(b., '') LIKE '%装配%' THEN 0
ELSE ISNULL(q., CASE
WHEN b. NOT IN ('异常') THEN ISNULL(b., 0)
WHEN b. = '异常' THEN -ISNULL(b., 0)
ELSE 0
END)
END AS VARCHAR(20)) AS ,
CONVERT(VARCHAR(19), b., 120) AS ,
CONVERT(VARCHAR(19), b., 120) AS ,
CAST(CAST(b. / 60.0 / 60.0 AS DECIMAL(10,2)) AS VARCHAR(20)) AS '工时(h)'
FROM b
LEFT JOIN TaskStart报工数量 q
ON q.TaskAID = b.TaskAID
AND q. = CONVERT(VARCHAR(19), b., 120)
ORDER BY b., b.
END
GO

View File

@@ -0,0 +1,253 @@
USE [YL_MESDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[_工时查询_工序工时_查询]
@ NVARCHAR(50) = NULL,
@ NVARCHAR(100) = NULL,
@ NVARCHAR(50) = NULL,
@ DATE = NULL,
@ DATE = NULL,
@ INT = 100
AS
BEGIN
SET NOCOUNT ON;
;WITH AS (
SELECT TOP (CASE WHEN ISNULL(@, 0) <= 0 THEN 100 ELSE @ END)
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.TaskAID,
v.,
CASE
WHEN ISNULL(v., '') LIKE '%辅助%' OR ISNULL(v., '') LIKE '%辅助%' THEN '调机'
WHEN ISNULL(v., '') LIKE '%报工%' OR ISNULL(v., '') LIKE '%报工%' THEN '正常'
ELSE ISNULL(NULLIF(v., ''), v.)
END AS ,
p. AS
FROM [dbo].[View_生产工时视图] v
LEFT JOIN [dbo].[_零件生产工艺_工艺库] p
ON v. = p.
AND v. = p.
WHERE (@ IS NULL OR @ = '' OR v. >= @)
AND (@ IS NULL OR @ = '' OR v. < DATEADD(DAY, 1, @))
AND (@ IS NULL OR @ = '' OR v. LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR v. LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR v. = @)
AND (ISNULL(v., '') IN ('报工', '辅助结束') OR ISNULL(v., '') IN ('报工', '辅助结束'))
AND ISNULL(v., 0) > 0
ORDER BY v. DESC
),
AS (
SELECT DISTINCT
TaskAID,
CONVERT(VARCHAR(19), , 120) AS
FROM
),
TaskStart报工数量 AS (
SELECT
TaskAID,
CONVERT(VARCHAR(19), , 120) AS ,
MAX(CASE
WHEN = '异常' THEN -ISNULL(, 0)
ELSE ISNULL(, 0)
END) AS
FROM [dbo].[View_生产工时视图全部]
GROUP BY TaskAID, CONVERT(VARCHAR(19), , 120)
),
TaskStart扩展 AS (
SELECT
k.TaskAID,
k.,
CASE
WHEN EXISTS (
SELECT 1
FROM [dbo].[View_生产工时视图全部] v
WHERE v.TaskAID = k.TaskAID
AND CONVERT(VARCHAR(19), v., 120) = k.
AND ISNULL(v., '') LIKE '%白班%'
) THEN '白班'
WHEN EXISTS (
SELECT 1
FROM [dbo].[View_生产工时视图全部] v
WHERE v.TaskAID = k.TaskAID
AND CONVERT(VARCHAR(19), v., 120) = k.
AND ISNULL(v., '') LIKE '%夜班%'
) THEN '夜班'
ELSE ''
END AS ,
(
SELECT STRING_AGG(x., ',')
FROM (
SELECT DISTINCT LTRIM(RTRIM(v2.)) AS
FROM [dbo].[View_生产工时视图全部] v2
WHERE v2.TaskAID = k.TaskAID
AND CONVERT(VARCHAR(19), v2., 120) = k.
AND ISNULL(v2., 0) <= 0
AND NULLIF(LTRIM(RTRIM(ISNULL(v2., ''))), '') IS NOT NULL
) x
) AS
FROM k
),
AS (
SELECT
b.TaskAID,
ISNULL(b., '') + ' ' + ISNULL(b., '') + ' ' + ISNULL(b., '') + '' + CAST(ISNULL(b., 0) AS VARCHAR(50)) AS ,
CONVERT(VARCHAR(10), b., 120) AS ,
e.,
e.,
b. AS ,
b.,
qv.,
b. AS ,
CAST(ISNULL(b., 0) / 60.0 / 60.0 AS DECIMAL(10, 2)) AS ,
CAST(ISNULL(b., 0) / 60.0 AS DECIMAL(10, 2)) AS ,
'' AS ,
CASE
WHEN qv. > 0 THEN CAST((ISNULL(b., 0) / 60.0) / qv. AS DECIMAL(10, 2))
ELSE CAST(ISNULL(b., 0) AS DECIMAL(10, 2))
END AS ,
b.,
CONVERT(VARCHAR(19), b., 120) AS
FROM b
LEFT JOIN TaskStart报工数量 q
ON q.TaskAID = b.TaskAID
AND q. = CONVERT(VARCHAR(19), b., 120)
LEFT JOIN TaskStart扩展 e
ON e.TaskAID = b.TaskAID
AND e. = CONVERT(VARCHAR(19), b., 120)
CROSS APPLY (
SELECT CASE
WHEN ISNULL(b., '') LIKE '%装配%' THEN 0
ELSE ISNULL(q., ISNULL(b., 0))
END AS
) qv
),
AS (
SELECT
TaskAID,
,
,
MAX() AS
FROM
GROUP BY TaskAID, ,
),
Task数量汇总 AS (
SELECT TaskAID, SUM() AS
FROM
GROUP BY TaskAID
),
AS (
SELECT TaskAID, , SUM() AS
FROM
GROUP BY TaskAID,
),
Task汇总 AS (
SELECT
m.TaskAID,
MAX(m.) AS ,
COUNT(*) AS ,
ISNULL(q., 0) AS ,
SUM(m.) AS ,
SUM(m.) AS ,
MAX(m.) AS
FROM m
LEFT JOIN Task数量汇总 q ON q.TaskAID = m.TaskAID
GROUP BY m.TaskAID, q.
),
AS (
SELECT
m.TaskAID,
MAX(m.) AS ,
m.,
COUNT(*) AS ,
ISNULL(q., 0) AS ,
SUM(m.) AS ,
SUM(m.) AS ,
MAX(m.) AS
FROM m
LEFT JOIN q ON q.TaskAID = m.TaskAID AND q. = m.
GROUP BY m.TaskAID, m., q.
)
SELECT
1 AS [Level],
TaskAID,
AS taskDescription,
'' AS dateLabel,
'' AS shift,
'' AS operatorNames,
'' AS productionOrderNo,
'' AS reportType,
CAST( AS VARCHAR(20)) AS reportQty,
'' AS station,
CAST( AS VARCHAR(20)) AS workHours,
CAST( AS VARCHAR(20)) AS actualWorkHours,
'' AS programTime,
CAST(CASE WHEN > 0 THEN / ELSE ISNULL(, 0) END AS VARCHAR(20)) AS pieceWorkHours,
CAST(ISNULL(, 0) AS VARCHAR(20)) AS processWorkHours,
'' AS startTime,
CAST( AS VARCHAR(20)) AS reportCount
FROM Task汇总
UNION ALL
SELECT
2 AS [Level],
TaskAID,
AS taskDescription,
AS dateLabel,
'' AS shift,
'' AS operatorNames,
'' AS productionOrderNo,
'' AS reportType,
CAST( AS VARCHAR(20)) AS reportQty,
'' AS station,
CAST( AS VARCHAR(20)) AS workHours,
CAST( AS VARCHAR(20)) AS actualWorkHours,
'' AS programTime,
CAST(CASE WHEN > 0 THEN / ELSE ISNULL(, 0) END AS VARCHAR(20)) AS pieceWorkHours,
CAST(ISNULL(, 0) AS VARCHAR(20)) AS processWorkHours,
'' AS startTime,
CAST( AS VARCHAR(20)) AS reportCount
FROM
UNION ALL
SELECT
3 AS [Level],
TaskAID,
AS taskDescription,
AS dateLabel,
AS shift,
ISNULL(, '') AS operatorNames,
ISNULL(, '') AS productionOrderNo,
ISNULL(, '') AS reportType,
CAST( AS VARCHAR(20)) AS reportQty,
ISNULL(, '') AS station,
CAST( AS VARCHAR(20)) AS workHours,
CAST( AS VARCHAR(20)) AS actualWorkHours,
AS programTime,
CAST( AS VARCHAR(20)) AS pieceWorkHours,
CAST(ISNULL(, 0) AS VARCHAR(20)) AS processWorkHours,
AS startTime,
'' AS reportCount
FROM
ORDER BY TaskAID, dateLabel, [Level], startTime
END
GO

View File

@@ -0,0 +1,238 @@
CREATE PROCEDURE [dbo].[_工时查询_工序工时_查询]
@ NVARCHAR(50) = NULL,
@ NVARCHAR(100) = NULL,
@ NVARCHAR(50) = NULL,
@ DATE = NULL,
@ DATE = NULL,
@ int = 100
AS
BEGIN
SET NOCOUNT ON;
-- 获取班次信息
DECLARE @ TIME = '07:45:00'
DECLARE @ TIME = '16:30:00'
DECLARE @ TIME = '16:30:00'
DECLARE @ TIME = '00:40:00'
;WITH AS (
SELECT top (@)
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.,
v.TaskAID,
v.,
-- 根据时间判断班次
CASE
WHEN CAST(v. AS TIME) >= @
AND CAST(v. AS TIME) < @ THEN '白班'
WHEN CAST(v. AS TIME) >= @
OR CAST(v. AS TIME) < @ THEN '夜班'
ELSE '其他'
END AS ,
-- 标记实际工时和辅助工时
CASE WHEN v. = '报工' THEN v. ELSE 0 END AS ,
CASE WHEN v. = '辅助结束' THEN v. ELSE 0 END AS ,
-- 标记报工数量和辅助数量
CASE WHEN v. = '报工' THEN v. ELSE 0 END AS ,
CASE WHEN v. = '辅助结束' THEN v. ELSE 0 END AS ,
-- 关联工艺库获取标准工时(工艺工时)
p. AS
FROM View_生产工时视图 v
LEFT JOIN _零件生产工艺_工艺库 p
ON v. = p.
AND v. = p.
WHERE (@ IS NULL OR @ = '' OR v. >= @)
AND (@ IS NULL OR @ = '' OR v. >= @)
AND (@ IS NULL OR @ = '' OR v. LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR v. LIKE '%' + @ + '%')
AND (@ IS NULL OR @ = '' OR v. = @)
-- 去掉报工时间为0的数据实际加工工时或辅助加工工时不为0
AND (CASE WHEN v. = '报工' THEN v. ELSE 0 END > 0
OR CASE WHEN v. = '辅助结束' THEN v. ELSE 0 END > 0)
),
-- 获取每个TaskAID对应的任务描述取第一条记录
Task描述 AS (
SELECT DISTINCT
TaskAID,
-- 任务描述:产品名称 + 产品编码 + 工序名称
ISNULL(, '') + ' ' + ISNULL(, '') + ' ' + ISNULL(, '') + ''+ CAST( AS VARCHAR(50)) AS
FROM
),
-- 第一层按TaskAID汇总
TaskAID汇总 AS (
SELECT
b.TaskAID,
t.,
'' AS ,
'' AS ,
COUNT(*) AS ,
SUM() AS ,
SUM() AS ,
CAST(SUM() / 60.0 / 60.0 AS DECIMAL(10,1)) AS ,
CAST(SUM() / 60.0 / 60.0 AS DECIMAL(10,1)) AS ,
-- 计算平均实际工时(实际加工工时/实际报工数量)
CASE
WHEN SUM() > 0
THEN CAST((SUM() / 60.0 / 60.0) / SUM() AS DECIMAL(10,2))
ELSE 0
END AS ,
-- 计算平均辅助工时(辅助加工工时/辅助报工数量)
CASE
WHEN SUM() > 0
THEN CAST((SUM() / 60.0 / 60.0) / SUM() AS DECIMAL(10,2))
ELSE 0
END AS ,
-- 工艺工时(取第一条记录的工艺工时)
MAX(b.) AS
FROM b
LEFT JOIN Task描述 t ON b.TaskAID = t.TaskAID
GROUP BY b.TaskAID, t.
),
-- 第二层按TaskAID和日期汇总
AS (
SELECT
b.TaskAID,
t.,
CONVERT(VARCHAR(10), b., 120) AS ,
'' AS ,
COUNT(*) AS ,
SUM() AS ,
SUM() AS ,
CAST(SUM() / 60.0 / 60.0 AS DECIMAL(10,1)) AS ,
CAST(SUM() / 60.0 / 60.0 AS DECIMAL(10,1)) AS ,
-- 计算平均实际工时(实际加工工时/实际报工数量)
CASE
WHEN SUM() > 0
THEN CAST((SUM() / 60.0 / 60.0) / SUM() AS DECIMAL(10,2))
ELSE 0
END AS ,
-- 计算平均辅助工时(辅助加工工时/辅助报工数量)
CASE
WHEN SUM() > 0
THEN CAST((SUM() / 60.0 / 60.0) / SUM() AS DECIMAL(10,2))
ELSE 0
END AS ,
-- 工艺工时(取该日期第一条记录的工艺工时)
MAX(b.) AS
FROM b
LEFT JOIN Task描述 t ON b.TaskAID = t.TaskAID
GROUP BY b.TaskAID, t., CONVERT(VARCHAR(10), b., 120)
),
-- 第三层按TaskAID、日期和班次汇总
AS (
SELECT
b.TaskAID,
t.,
CONVERT(VARCHAR(10), b., 120) AS ,
b.,
b.,
COUNT(*) AS ,
SUM() AS ,
SUM() AS ,
CAST(SUM() / 60.0 / 60.0 AS DECIMAL(10,1)) AS ,
CAST(SUM() / 60.0 / 60.0 AS DECIMAL(10,1)) AS ,
-- 计算平均实际工时(实际加工工时/实际报工数量)
CASE
WHEN SUM() > 0
THEN CAST((SUM() / 60.0 / 60.0) / SUM() AS DECIMAL(10,2))
ELSE 0
END AS ,
-- 计算平均辅助工时(辅助加工工时/辅助报工数量)
CASE
WHEN SUM() > 0
THEN CAST((SUM() / 60.0 / 60.0) / SUM() AS DECIMAL(10,2))
ELSE 0
END AS ,
-- 工艺工时(取该班次第一条记录的工艺工时)
MAX(b.) AS
FROM b
LEFT JOIN Task描述 t ON b.TaskAID = t.TaskAID
GROUP BY b.TaskAID, t., CONVERT(VARCHAR(10), b., 120), b., b.
)
-- 第一层TaskAID汇总
SELECT
1 AS [Level],
TaskAID,
AS taskDescription,
'' AS dateLabel,
'' AS shift,
'' AS ,
CAST( AS VARCHAR(20)) AS reportQty,
CAST( AS VARCHAR(20)) AS actualWorkHours,
CAST( AS VARCHAR(20)) AS auxiliaryWorkHours,
CAST( AS VARCHAR(20)) AS avgActualWorkHours,
CAST( AS VARCHAR(20)) AS avgAuxiliaryWorkHours,
CAST(ISNULL(, 0) AS VARCHAR(20)) AS processWorkHours, -- 工艺工时
'' AS contractNo,
'' AS orderNo,
'' AS productCode,
'' AS productName,
'' AS processName,
CAST( AS VARCHAR(20)) AS reportCount
FROM TaskAID汇总
WHERE > 0 OR > 0
UNION ALL
-- 第二层:日期汇总
SELECT
2 AS [Level],
TaskAID,
AS taskDescription,
AS dateLabel,
'' AS shift,
'' AS ,
CAST( AS VARCHAR(20)) AS reportQty,
CAST( AS VARCHAR(20)) AS actualWorkHours,
CAST( AS VARCHAR(20)) AS auxiliaryWorkHours,
CAST( AS VARCHAR(20)) AS avgActualWorkHours,
CAST( AS VARCHAR(20)) AS avgAuxiliaryWorkHours,
CAST(ISNULL(, 0) AS VARCHAR(20)) AS processWorkHours, -- 工艺工时
'' AS contractNo,
'' AS orderNo,
'' AS productCode,
'' AS productName,
'' AS processName,
CAST( AS VARCHAR(20)) AS reportCount
FROM
WHERE > 0 OR > 0
UNION ALL
-- 第三层:班次汇总
SELECT
3 AS [Level],
TaskAID,
AS taskDescription,
AS dateLabel,
AS shift,
AS ,
CAST( AS VARCHAR(20)) AS reportQty,
CAST( AS VARCHAR(20)) AS actualWorkHours,
CAST( AS VARCHAR(20)) AS auxiliaryWorkHours,
CAST( AS VARCHAR(20)) AS avgActualWorkHours,
CAST( AS VARCHAR(20)) AS avgAuxiliaryWorkHours,
CAST(ISNULL(, 0) AS VARCHAR(20)) AS processWorkHours, -- 工艺工时
'' AS contractNo,
'' AS orderNo,
'' AS productCode,
'' AS productName,
'' AS processName,
CAST( AS VARCHAR(20)) AS reportCount
FROM
WHERE > 0 OR > 0
ORDER BY TaskAID, dateLabel, shift, [Level]
END

BIN
doc/修改工时报表.docx Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
doc/工时查询界面.docx Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
doc/设备信息.xlsx Normal file

Binary file not shown.

1167
gptlog-process/gpdlog.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
<template>
<div class="app-container">
<el-card style="height: 850px">
<div style="margin-top: 7px; margin-bottom: 7px">
<el-input v-model="equipmentName" placeholder="设备名称" size="small" clearable style="width:200px;margin-left: 0px"/>
<el-select v-model="equipmentType" placeholder="设备类型" filterable size="small" style="width:200px" clearable >
<div class="app-container device-information-page">
<el-card class="device-card">
<div class="filter-bar">
<el-input v-model="equipmentName" placeholder="生产用名" size="small" clearable class="filter-control"/>
<el-select v-model="equipmentType" placeholder="设备类型" filterable size="small" clearable class="filter-control">
<el-option
v-for="item in basedatalx"
:key="item.id"
@@ -11,63 +11,52 @@
:value="item.id"
/>
</el-select>
<!-- <el-input v-model="opName" placeholder="工位" size="small" clearable style="width:200px;margin-left: 0px"/> -->
<el-button type="primary" icon="el-icon-search" size="small" style="margin-left: 20px" plain @click="pageSize = 20;pageCurrent = 1;searchTable()">查询</el-button>
<el-button type="primary" icon="el-icon-search" size="small" plain @click="pageSize = 20; pageCurrent = 1; searchTable()">查询</el-button>
<el-tooltip effect="dark" content="添加新设备" placement="top">
<el-button type="distribution" icon="el-icon-circle-plus-outline" size="small" style="margin-left: 10px" @click="ADD()">设备</el-button>
<el-button type="distribution" icon="el-icon-circle-plus-outline" size="small" @click="ADD()">设备</el-button>
</el-tooltip>
</div>
<div>
<el-table :data="tableData" border size="small" stripe highlight-current-row height="740px" style="width: 1048px">
<el-table-column label="设备名称" prop="设备名称" align="center" width="150px" >
<template slot-scope="scope">
{{ scope.row.设备名称 }}
</template>
</el-table-column>
<el-table-column label="设备型号" prop="设备型号" align="center" width="150px" >
<template slot-scope="scope">
{{ scope.row.设备型号 }}
</template>
</el-table-column>
<el-table-column label="设备类型" prop="设备类型名称" align="center" width="150px" >
<template slot-scope="scope">
{{ scope.row.设备类型名称 }}
</template>
</el-table-column>
<!-- <el-table-column label="加工工艺" align="center" width="150px">
<template slot-scope="scope">
{{ scope.row.加工工艺 }}
</template>
</el-table-column> -->
<!-- <el-table-column label="工位" align="center" width="80px">
<template slot-scope="scope">
{{ scope.row.工位号 }}
</template>
</el-table-column> -->
<!-- <el-table-column label="工时单价(元/小时)" align="center" width="140px">
<template slot-scope="scope">
{{ scope.row.工时单价 }}
</template>
</el-table-column>
<el-table-column label="月设备加工能力" align="center" width="140px">
<template slot-scope="scope">
{{ scope.row.月设备加工能力 }}
</template>
</el-table-column>
<el-table-column label="点检类型名称" align="center" width="137px">
<template slot-scope="scope">
{{ scope.row.点检表类型名称 }}
</template>
</el-table-column> -->
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="text" size="mini" icon="el-icon-edit" style="margin-right:10px" @click="handleEdit(scope.row)"/>
<el-button type="text" size="mini" icon="el-icon-delete" @click="handleDelete(scope.row)"/>
</template>
</el-table-column>
</el-table>
</div>
<div class="block" style="margin-top: 10px;">
<el-table
:data="sortedTableData"
:row-class-name="tableRowClassName"
border
size="small"
stripe
highlight-current-row
height="740px"
class="device-table">
<el-table-column label="设备名称" prop="名称" align="center" width="150" show-overflow-tooltip/>
<el-table-column label="公司编码(财务)" prop="公司编码" align="center" width="140" show-overflow-tooltip/>
<el-table-column label="生产用名" prop="设备名称" align="center" width="150" show-overflow-tooltip/>
<el-table-column label="规格/型号" prop="设备型号" align="center" width="150" show-overflow-tooltip/>
<el-table-column label="设备类型" prop="设备类型名称" align="center" width="130" show-overflow-tooltip/>
<el-table-column label="设备信息" prop="设备信息" align="center" width="160" show-overflow-tooltip/>
<el-table-column label="使用部门" prop="使用部门" align="center" width="120" show-overflow-tooltip/>
<el-table-column label="入账日期" prop="入账日期" align="center" width="120">
<template slot-scope="scope">{{ formatDate(scope.row.入账日期) }}</template>
</el-table-column>
<el-table-column label="单位" prop="单位" align="center" width="80" show-overflow-tooltip/>
<el-table-column label="数量" prop="数量" align="center" width="90" show-overflow-tooltip/>
<el-table-column label="状态" prop="状态" align="center" width="100" show-overflow-tooltip/>
<el-table-column label="维修记录" prop="维修记录" align="center" width="160" show-overflow-tooltip/>
<el-table-column label="维保记录" prop="维保记录" align="center" width="160" show-overflow-tooltip/>
<el-table-column label="工位绑定" prop="工位绑定" align="center" width="180" show-overflow-tooltip>
<template slot-scope="scope">{{ formatStationNames(scope.row.工位绑定) }}</template>
</el-table-column>
<el-table-column label="主要设备" prop="主要设备" align="center" width="90" show-overflow-tooltip/>
<el-table-column label="设备标准开机工时(小时)" prop="设备标准开机工时" align="center" width="170" show-overflow-tooltip/>
<el-table-column label="特种设备" prop="特种设备" align="center" width="90" show-overflow-tooltip/>
<el-table-column label="证书有效期至" prop="证书有效期至" align="center" width="130">
<template slot-scope="scope">{{ formatDate(scope.row.证书有效期至) }}</template>
</el-table-column>
<el-table-column label="操作" align="center" fixed="right" width="90">
<template slot-scope="scope">
<el-button type="text" size="mini" icon="el-icon-edit" style="margin-right:10px" @click="handleEdit(scope.row)"/>
<el-button type="text" size="mini" icon="el-icon-delete" @click="handleDelete(scope.row)"/>
</template>
</el-table-column>
</el-table>
<div class="pagination-bar">
<el-pagination
:current-page="pageCurrent"
:page-sizes="[10, 20, 30, 40, 100]"
@@ -79,22 +68,32 @@
/>
</div>
</el-card>
<el-dialog :title="title" :visible.sync="dialogFormVisible" center style="min-height: 300px" width="700px">
<el-form ref="form" :model="form" :rules="rules" label-position="right" label-width="110px" class="demo-ruleForm">
<el-dialog :title="title" :visible.sync="dialogFormVisible" center width="980px">
<el-form ref="form" :model="form" :rules="rules" label-position="right" label-width="150px" class="device-form">
<el-row>
<el-col :span="12">
<el-form-item label="设备名称" prop="设备名称" >
<el-input v-model="form.设备名称" placeholder="设备名称" size="small" style="width:200px" clearable />
<el-form-item label="设备名称" prop="名称">
<el-input v-model="form.名称" placeholder="设备名称" size="small" clearable/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="设备型号" prop="设备型号" >
<el-input v-model="form.设备型号" placeholder="设备型号" size="small" style="width:200px" clearable />
<el-form-item label="公司编码(财务)" prop="公司编码">
<el-input v-model="form.公司编码" :disabled="title === '编辑设备'" placeholder="公司编码(财务)" size="small" clearable/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="设备类型" prop="设备类型" >
<el-select v-model="form.设备类型" placeholder="设备类型" filterable size="small" style="width:200px" clearable >
<el-form-item label="生产用名" prop="设备名称">
<el-input v-model="form.设备名称" placeholder="生产用名" size="small" clearable/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="规格/型号" prop="设备型号">
<el-input v-model="form.设备型号" placeholder="规格/型号" size="small" clearable/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="设备类型" prop="设备类型">
<el-select v-model="form.设备类型" placeholder="设备类型" filterable size="small" clearable>
<el-option
v-for="item in basedatalx"
:key="item.id"
@@ -104,55 +103,92 @@
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- <el-row>
<el-col :span = "12">
<el-form-item label="加工工艺" prop="加工工艺" >
<el-select v-model="form.加工工艺" placeholder="加工工艺" filterable size="small" style="width:200px" clearable >
<el-col :span="12">
<el-form-item label="设备信息" prop="设备信息">
<el-input v-model="form.设备信息" placeholder="设备信息" size="small" clearable/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="使用部门" prop="使用部门">
<el-input v-model="form.使用部门" placeholder="使用部门" size="small" clearable/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="入账日期" prop="入账日期">
<el-date-picker v-model="form.入账日期" type="date" placeholder="入账日期" size="small"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="单位" prop="单位">
<el-input v-model="form.单位" placeholder="单位" size="small" clearable/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="数量" prop="数量">
<el-input v-positive="'float'" v-model="form.数量" type="number" placeholder="数量" size="small" clearable/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="状态" prop="状态">
<el-input v-model="form.状态" placeholder="状态" size="small" clearable/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="维修记录" prop="维修记录">
<el-input v-model="form.维修记录" placeholder="维修记录" size="small" clearable/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="维保记录" prop="维保记录">
<el-input v-model="form.维保记录" placeholder="维保记录" size="small" clearable/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工位绑定" prop="工位绑定">
<el-select v-model="form.工位绑定" placeholder="工位绑定" filterable multiple collapse-tags size="small" clearable>
<el-option
v-for="item in process"
v-for="item in stationOptions"
:key="item.value"
:label="item.label"
:value="item.value"/>
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span = "12">
<el-form-item label="工位号" prop="工位号" >
<el-input v-model="form.工位号" placeholder="工位号" size="small" style="width:200px" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span = "12">
<el-form-item label="工时单价" prop="工时单价" >
<el-input v-positive="'float'" v-model="form.工时单价" class="工时单价" size="small" style="width:200px" placeholder="工时单价" type="number"/>
</el-form-item>
</el-col>
<el-col :span = "12">
<el-form-item label="月设备加工能力" prop="月设备加工能力" >
<el-input v-positive="'float'" v-model="form.月设备加工能力" class="工时单价" size="small" style="width:200px" placeholder="月设备加工能力" type="number"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span = "12">
<el-form-item label="点检类型" prop="点检类型" >
<el-select v-model="form.点检类型" placeholder="选择点检类型" filterable size="small" style="width:200px" clearable >
<el-option
v-for="item in routineCheckType"
:key="item.value"
:label="item.label"
:value="item.value"/>
<el-col :span="12">
<el-form-item label="主要设备" prop="主要设备">
<el-select v-model="form.主要设备" placeholder="主要设备" size="small" clearable>
<el-option label="是" value="是"/>
<el-option label="否" value="否"/>
</el-select>
</el-form-item>
</el-col>
</el-row> -->
<el-col :span="12">
<el-form-item label="设备标准开机工时" prop="设备标准开机工时">
<el-input v-positive="'float'" v-model="form.设备标准开机工时" type="number" placeholder="小时" size="small" clearable>
<template slot="append">小时</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="特种设备" prop="特种设备">
<el-select v-model="form.特种设备" placeholder="特种设备" size="small" clearable>
<el-option label="是" value="是"/>
<el-option label="否" value="否"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="证书有效期至" prop="证书有效期至">
<el-date-picker v-model="form.证书有效期至" type="date" placeholder="证书有效期至" size="small"/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="callOff('form')">取消</el-button>
<el-button v-show="title==='新增设备'" type="primary" @click="submitAdd('form')">确定</el-button>
<el-button v-show="title==='编辑设备'" type="primary" @click="submitEdit('form')">确定</el-button>
<el-button v-show="title === '新增设备'" type="primary" @click="submitAdd('form')">确定</el-button>
<el-button v-show="title === '编辑设备'" type="primary" @click="submitEdit('form')">确定</el-button>
</div>
</el-dialog>
</div>
@@ -160,80 +196,82 @@
<script>
import { mapGetters } from 'vuex'
const emptyForm = () => ({
名称: '',
公司编码: '',
设备名称: '',
设备型号: '',
设备类型: '',
设备信息: '',
使用部门: '',
入账日期: null,
单位: '',
数量: '',
状态: '',
维修记录: '',
维保记录: '',
工位绑定: [],
主要设备: '',
设备标准开机工时: '',
特种设备: '',
证书有效期至: null
})
export default {
name: 'DeviceInformation',
data() {
const validateCompanyCode = (rule, value, callback) => {
if (this.title === '新增设备' && !value) {
callback(new Error('请输入公司编码'))
} else {
callback()
}
}
return {
routineCheckType: [],
dialogFormVisible: false,
title: '',
equipmentValue: '',
equipmentName: '',
equipmentType: '',
opName: '',
process: [],
form: {
设备名称: '',
设备型号: '',
设备类型: ''
// 加工工艺: '',
// 工位号: '',
// 点检类型: '',
// 工时单价: '',
// 月设备加工能力: ''
},
form: emptyForm(),
basedatalx: [],
stationOptions: [],
rules: {
设备名称: [{ required: true, message: '请输入设备名称' }],
// 设备型号: [{ required: true, message: '请输入设备型号' }],
// 加工工艺: [{ required: true, message: '请选择加工工艺' }],
设备类型: [{ required: true, message: '请选择' }]
公司编码: [{ validator: validateCompanyCode, trigger: 'blur' }],
设备名称: [{ required: true, message: '请输入生产用名', trigger: 'blur' }]
},
original: '',
total: 0, // 分页总数
tableData: [], // 设备信息表
pageCurrent: 1, // 分页当前页
pageSize: 20 // 分页每页显示条数
total: 0,
tableData: [],
pageCurrent: 1,
pageSize: 20
}
},
computed: {
...mapGetters([
'id',
'token'
])
]),
sortedTableData() {
return [...this.tableData].sort((a, b) => {
const aLevel = this.getCertificateLevel(a.证书有效期至)
const bLevel = this.getCertificateLevel(b.证书有效期至)
if (aLevel !== bLevel) return aLevel - bLevel
return this.getDateTime(a.证书有效期至) - this.getDateTime(b.证书有效期至)
})
}
},
created() {
this.searchTable()
this.getbasedata()
// this.getRoutineCheckType()
this.getStationOptions()
},
methods: {
// getRoutineCheckType() {
// var param = []
// var Data = this.CreateData('11', '点检类型_查询', param)
// this.ExecDatabase(Data).then(response => {
// for (let i = 0; i < response.data.length; i++) {
// this.routineCheckType.push({
// label: response.data[i].点检表类型名称,
// value: response.data[i].点检表类型流水号
// })
// }
// })
// },
// getProcess() {
// var param = []
// var Data = this.CreateData('11', '工艺名称_查询', param)
// this.ExecDatabase(Data).then(response => {
// for (let i = 0; i < response.data.length; i++) {
// this.process.push({
// label: response.data[i].工艺名称,
// value: response.data[i].工艺编号
// })
// }
// })
// },
getbasedata() {
var Data = this.CreateData('11', '查询字典')
this.ExecDatabase(Data).then(response => {
this.basedatalx = []
response.data.forEach(element => {
if (element.数据类别 == '设备类型') {
this.basedatalx.push({
@@ -244,11 +282,19 @@ export default {
})
})
},
getStationOptions() {
var Data = this.CreateData('11', 'MES_登录_工位与名称_查询', [])
this.ExecDatabase(Data).then(response => {
this.stationOptions = (response.data || []).map(item => ({
label: item.指南工位号 || item.工位名称 || item.工位号,
value: item.工位号
}))
})
},
searchTable() {
let equipmentName_check, equipmentType_check
this.equipmentName ? equipmentName_check = 1 : equipmentName_check = 0
this.equipmentType ? equipmentType_check = 1 : equipmentType_check = 0
// this.opName ? opName_check = 1 : opName_check = 0
var param = []
param[0] = ['设备名称_check', equipmentName_check]
param[1] = ['设备名称', this.equipmentName]
@@ -256,43 +302,52 @@ export default {
param[3] = ['设备类型_check', equipmentType_check]
var Data = this.CreateData('11', '设备管理_设备信息_查询', param, this.pageSize, this.pageCurrent)
this.ExecDatabase(Data).then(response => {
this.tableData = response.data.rows
this.total = response.data.total
this.tableData = response.data.rows || []
this.total = response.data.total || 0
})
},
ADD() {
this.title = '新增设备'
if (this.$refs['form'] !== undefined) {
this.$refs['form'].resetFields()
if (this.$refs.form !== undefined) {
this.$refs.form.resetFields()
}
this.form.设备名称 = ''
this.form.设备型号 = ''
this.form.设备类型 = ''
// this.form.加工工艺 = ''
// this.form.工位号 = ''
// this.form.月设备加工能力 = ''
// this.form.点检类型 = 1
// this.form.工时单价 = ''
this.form = emptyForm()
this.dialogFormVisible = true
},
handleEdit(row) {
this.title = '编辑设备'
if (this.$refs['form'] !== undefined) {
this.$refs['form'].resetFields()
if (this.$refs.form !== undefined) {
this.$refs.form.resetFields()
}
this.equipmentValue = row.设备流水号
this.form.设备名称 = row.设备名称
this.form.设备型号 = row.设备型号
console.log(this.basedatalx)
this.form.设备类型 = parseInt(row.设备类型)
// this.form.加工工艺 = Number(row.工艺编号)
// this.form.工位号 = row.工位号
// this.original = row.工位号
// this.form.点检类型 = Number(row.点检表类型)
// this.form.月设备加工能力 = row.月设备加工能力
// this.form.工时单价 = row.工时单价
const editForm = {
名称: row.名称 || '',
公司编码: row.公司编码 || '',
设备名称: row.设备名称 || '',
设备型号: row.设备型号 || '',
设备类型: row.设备类型 ? parseInt(row.设备类型) : '',
设备信息: row.设备信息 || '',
使用部门: row.使用部门 || '',
入账日期: this.parseDateValue(row.入账日期 || row['入账日期']),
单位: row.单位 || '',
数量: row.数量 || '',
状态: row.状态 || '',
维修记录: row.维修记录 || '',
维保记录: row.维保记录 || '',
工位绑定: this.parseStationBinding(row.工位绑定),
主要设备: row.主要设备 || '',
设备标准开机工时: row.设备标准开机工时 || '',
特种设备: row.特种设备 || '',
证书有效期至: this.parseDateValue(row.证书有效期至 || row['证书有效期至'])
}
Object.keys(editForm).forEach(key => {
this.$set(this.form, key, editForm[key])
})
this.dialogFormVisible = true
this.$nextTick(() => {
this.$set(this.form, '入账日期', editForm.入账日期)
this.$set(this.form, '证书有效期至', editForm.证书有效期至)
})
},
callOff(formName) {
this.dialogFormVisible = false
@@ -301,21 +356,7 @@ export default {
submitAdd(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
// var param = []
// param[0] = ['工位', this.form.工位号]
// var Data = this.CreateData('11', '设备管理_设备信息_验证工位号是否重复', param)
// this.ExecDatabase(Data).then(response => {
// if (Number(response.data[0].Column1) === 0) {
var param = []
param[0] = ['设备名称', this.form.设备名称]
param[1] = ['设备型号', this.form.设备型号]
param[2] = ['设备类型', this.form.设备类型]
// param[2] = ['加工工艺', this.form.加工工艺]
// param[3] = ['工位', this.form.工位号]
// param[4] = ['工时单价', this.form.工时单价]
// param[5] = ['月设备加工能力', this.form.月设备加工能力]
// param[6] = ['点检类型', this.form.点检类型]
var Data = this.CreateData('12', '设备管理_设备信息_增加', param)
var Data = this.CreateData('12', '设备管理_设备信息_增加', this.buildSubmitParams())
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.$message.success('添加成功')
@@ -325,74 +366,49 @@ export default {
this.$message.error('添加失败')
}
})
// } else {
// // this.$message.warning('工位号重复')
// }
// })
}
})
},
submitEdit(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
if (this.form.工位号 === this.original) {
var param = []
param[0] = ['设备名称', this.form.设备名称]
param[1] = ['设备型号', this.form.设备型号]
param[2] = ['设备流水号', this.equipmentValue]
param[3] = ['设备类型', this.form.设备类型]
// param[2] = ['加工工艺', this.form.加工工艺]
// param[3] = ['工位', this.form.工位号]
// param[4] = ['工时单价', this.form.工时单价]
// param[5] = ['月设备加工能力', this.form.月设备加工能力]
// param[6] = ['设备流水号', this.equipmentValue]
// param[7] = ['原工位', this.original]
// param[8] = ['点检类型', this.form.点检类型]
var Data = this.CreateData('12', '设备管理_设备信息_编辑', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.$message.success('编辑成功')
this.searchTable()
this.dialogFormVisible = false
} else {
this.$message.error('编辑失败')
}
})
} else {
// var param1 = []
// param1[0] = ['工位', this.form.工位号]
// var Data1 = this.CreateData('11', '设备管理_设备信息_验证工位号是否重复', param1)
// this.ExecDatabase(Data1).then(response => {
// if (Number(response.data[0].Column1) === 0) {
var param = []
param[0] = ['设备名称', this.form.设备名称]
param[1] = ['设备型号', this.form.设备型号]
param[2] = ['设备流水号', this.equipmentValue]
param[3] = ['设备类型', this.form.设备类型]
// param[2] = ['加工工艺', this.form.加工工艺]
// param[3] = ['工位', this.form.工位号]
// param[4] = ['工时单价', this.form.工时单价]
// param[5] = ['月设备加工能力', this.form.月设备加工能力]
// param[6] = ['设备流水号', this.equipmentValue]
// param[7] = ['原工位', this.original]
var Data = this.CreateData('12', '设备管理_设备信息_编辑', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.$message.success('编辑成功')
this.searchTable()
this.dialogFormVisible = false
} else {
this.$message.error('编辑失败')
}
})
// } else {
// // this.$message.warning('工位号重复')
// }
// })
}
var param = this.buildSubmitParams()
param.unshift(['设备流水号', this.equipmentValue])
var Data = this.CreateData('12', '设备管理_设备信息_编辑', param)
this.ExecDatabase(Data).then(response => {
if (response.data[0].result === '1') {
this.$message.success('编辑成功')
this.searchTable()
this.dialogFormVisible = false
} else {
this.$message.error('编辑失败')
}
})
}
})
},
buildSubmitParams() {
return [
['名称', this.form.名称],
['公司编码', this.form.公司编码],
['设备名称', this.form.设备名称],
['设备型号', this.form.设备型号],
['设备类型', this.form.设备类型],
['设备信息', this.form.设备信息],
['使用部门', this.form.使用部门],
['入账日期', this.dateParam(this.form.入账日期)],
['单位', this.form.单位],
['数量', this.nullIfEmpty(this.form.数量)],
['状态', this.form.状态],
['维修记录', this.form.维修记录],
['维保记录', this.form.维保记录],
['工位绑定', (this.form.工位绑定 || []).join(',')],
['主要设备', this.form.主要设备],
['设备标准开机工时', this.nullIfEmpty(this.form.设备标准开机工时)],
['特种设备', this.form.特种设备],
['证书有效期至', this.dateParam(this.form.证书有效期至)]
]
},
handleDelete(row) {
this.$confirm('是否删除?', '提示', {
confirmButtonText: '确定',
@@ -426,8 +442,119 @@ export default {
handleCurrentChanges(val) {
this.pageCurrent = val
this.searchTable()
},
tableRowClassName({ row }) {
const level = this.getCertificateLevel(row.证书有效期至)
if (level === 0) return 'certificate-expired-row'
if (level === 1) return 'certificate-warning-row'
return ''
},
getCertificateLevel(value) {
const time = this.getDateTime(value)
if (!time) return 2
const today = new Date()
today.setHours(0, 0, 0, 0)
const warningEnd = new Date(today)
warningEnd.setDate(warningEnd.getDate() + 30)
if (time < today.getTime()) return 0
if (time <= warningEnd.getTime()) return 1
return 2
},
getDateTime(value) {
if (!value) return 0
const date = new Date(value)
if (Number.isNaN(date.getTime())) return 0
date.setHours(0, 0, 0, 0)
return date.getTime()
},
formatDate(value) {
if (!value) return ''
if (typeof value === 'string') {
const timestampMatch = value.match(/\/Date\((\d+)\)\//)
if (timestampMatch) return this.formatDate(new Date(Number(timestampMatch[1])))
const match = value.match(/\d{4}[-/.]\d{1,2}[-/.]\d{1,2}/)
return match ? match[0].replace(/[/.]/g, '-') : ''
}
const date = new Date(value)
if (Number.isNaN(date.getTime())) return ''
const month = `${date.getMonth() + 1}`.padStart(2, '0')
const day = `${date.getDate()}`.padStart(2, '0')
return `${date.getFullYear()}-${month}-${day}`
},
parseStationBinding(value) {
if (!value) return []
if (Array.isArray(value)) return value
return `${value}`.split(/[,]/).map(item => item.trim()).filter(item => item)
},
formatStationNames(value) {
const values = this.parseStationBinding(value)
if (values.length === 0) return ''
return values.map(value => {
const option = this.stationOptions.find(item => item.value === value)
return option ? option.label : value
}).join(',')
},
nullIfEmpty(value) {
return value === '' || value === undefined ? null : value
},
dateParam(value) {
if (value === null || value === undefined || value === '') return ''
return this.formatDate(value)
},
parseDateValue(value) {
if (!value) return null
if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value
const text = this.formatDate(value)
if (!text) return null
const parts = text.split('-').map(item => Number(item))
if (parts.length !== 3 || parts.some(item => Number.isNaN(item))) return null
return new Date(parts[0], parts[1] - 1, parts[2])
},
debugDateValue(label, value) {
if (process.env.NODE_ENV !== 'production') {
console.log(`[DeviceInformation] ${label}:`, value, this.parseDateValue(value))
}
}
}
}
</script>
<style scoped>
.device-card {
height: 850px;
}
.filter-bar {
display: flex;
align-items: center;
gap: 10px;
margin-top: 7px;
margin-bottom: 7px;
}
.filter-control {
width: 200px;
}
.device-table {
width: 100%;
}
.pagination-bar {
margin-top: 10px;
}
.device-form ::v-deep .el-input,
.device-form ::v-deep .el-select,
.device-form ::v-deep .el-date-editor {
width: 260px;
}
.device-information-page ::v-deep .certificate-expired-row td {
background-color: #fde2e2 !important;
}
.device-information-page ::v-deep .certificate-warning-row td {
background-color: #fdf6d3 !important;
}
</style>

View File

@@ -0,0 +1,544 @@
<template>
<div class="timely-kit-page">
<el-card>
<div class="search-container" @keyup.enter="searchTable">
<span class="show-text">生产订单:</span>
<el-input v-model="orderNo" clearable placeholder="请输入生产订单" class="filter-control" />
<span class="show-text">销售订单:</span>
<el-input v-model="contractNo" clearable placeholder="请输入销售订单" class="filter-control" />
<span class="show-text">物料编码:</span>
<el-input v-model="productCode" clearable placeholder="请输入产品编码" class="filter-control" />
<span class="show-text">计划号:</span>
<el-input v-model="planNo" clearable placeholder="请输入计划号" class="filter-control" />
<span class="show-text">发货状态:</span>
<el-select v-model="shipmentStatus" clearable placeholder="请选择" class="filter-control">
<el-option label="全部" value="全部" />
<el-option label="已下达发货通知" value="已发货" />
<el-option label="未下达发货通知" value="未发货" />
</el-select>
<span class="show-text">齐套:</span>
<el-select v-model="complete" clearable placeholder="请选择" class="small-filter">
<el-option label="全部" value="全部" />
<el-option label="是" value="是" />
<el-option label="否" value="否" />
</el-select>
<span class="show-text">完成状态:</span>
<el-select v-model="checkStatus" clearable placeholder="请选择" class="filter-control">
<el-option label="全部" value="" />
<el-option label="已完成" value="已完成" />
<el-option label="未完成" value="未完成" />
</el-select>
<span class="show-text">发料状态:</span>
<el-select v-model="sendStatus" clearable placeholder="请选择" class="filter-control">
<el-option label="全部" value="全部" />
<el-option label="发料齐套" value="发料齐套" />
<el-option label="发料缺件" value="发料缺件" />
<el-option label="未发料" value="未发料" />
</el-select>
<span class="show-text">自制件属性:</span>
<el-select v-model="selfStatus" clearable placeholder="请选择" class="filter-control">
<el-option label="全部" value="全部" />
<el-option label="机加" value="机加" />
<el-option label="装配" value="装配" />
</el-select>
<span class="show-text">计划开始:</span>
<el-date-picker
v-model="planStart"
clearable
format="yyyy-MM-dd"
placeholder="选择日期"
type="date"
value-format="yyyy-MM-dd"
class="filter-control"
/>
<el-button :disabled="loading" icon="el-icon-search" plain type="primary" @click="searchTable">查询</el-button>
</div>
<el-table
v-loading="loading"
:data="tableData"
:height="'78vh'"
border
element-loading-background="rgba(0, 0, 0, 0.2)"
element-loading-spinner="el-icon-loading"
highlight-current-row
size="mini"
style="width: 100%; margin-top: 16px"
tooltip-effect="dark"
>
<el-table-column type="expand">
<template slot-scope="scope">
<el-table
:data="scope.row.缺件明细"
border
size="mini"
class="detail-table"
:row-class-name="detailRowClassName"
>
<el-table-column align="center" label="序号" type="index" width="50" />
<el-table-column align="center" label="物料编码" prop="缺件物料编码" min-width="180" show-overflow-tooltip />
<el-table-column align="center" label="物料名称" prop="缺件物料名称" width="150" show-overflow-tooltip />
<el-table-column align="center" label="缺件数量" prop="缺件数量" width="90" />
<el-table-column align="center" label="属性" prop="缺件属性" width="90" />
<el-table-column align="center" label="生产订单号" prop="缺件生产订单号" width="100" />
<el-table-column align="center" label="进度" prop="进度" width="130" show-overflow-tooltip />
<el-table-column align="center" label="工艺路线/采购状态" min-width="520">
<template slot-scope="detail">
<div v-if="detail.row.缺件属性 === '外购'" class="purchase-route">
{{ detail.row.工艺路线 }}
</div>
<div v-else class="process-route" v-html="formatProcessRoute(detail.row)" />
</template>
</el-table-column>
<el-table-column align="center" label="预计完成时间" width="130">
<template slot-scope="detail">{{ formatDate(detail.row.预计完成时间) }}</template>
</el-table-column>
<el-table-column align="center" label="采购员" prop="采购员" width="90" show-overflow-tooltip />
<el-table-column align="center" label="采购未清数量" prop="采购未清数量" width="110" />
<el-table-column align="center" label="到货草稿" prop="到货草稿" width="90" />
<el-table-column align="center" label="质检状态" width="90">
<template slot-scope="detail">
<div :style="getStatusStyle(detail.row.质检状态)" class="score-cell">{{ detail.row.质检状态 }}</div>
</template>
</el-table-column>
</el-table>
</template>
</el-table-column>
<el-table-column align="center" label="序号" type="index" width="50" />
<el-table-column align="center" prop="合同号" label="销售订单" width="110" show-overflow-tooltip />
<el-table-column align="center" prop="计划号" label="计划号" width="100" show-overflow-tooltip />
<el-table-column align="center" prop="订单号" label="生产订单" width="90" />
<el-table-column align="center" prop="产品名称" label="产品名称" width="160" show-overflow-tooltip />
<el-table-column align="center" prop="产品编码" label="产品编码" min-width="210" show-overflow-tooltip />
<el-table-column align="center" prop="计划数量订单" label="计划数量" width="80" />
<el-table-column align="center" prop="入库数量" label="入库数量" width="80" />
<el-table-column align="center" label="要求完工日" width="120">
<template slot-scope="scope">{{ formatDate(scope.row.要求完工日期) }}</template>
</el-table-column>
<el-table-column align="center" label="要求发货日" width="120">
<template slot-scope="scope">{{ formatDate(scope.row.要求发货日期) }}</template>
</el-table-column>
<el-table-column align="center" label="预计齐套时间" width="130">
<template slot-scope="scope">{{ formatDate(scope.row.预计齐套时间) }}</template>
</el-table-column>
<el-table-column align="center" label="齐套" width="80">
<template slot-scope="scope">
<div :style="getStatusStyle(scope.row.齐套)" class="score-cell">{{ scope.row.齐套 }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="拣配状态" width="90">
<template slot-scope="scope">
<div :style="getStatusStyle(scope.row.拣配状态)" class="score-cell">{{ scope.row.拣配状态 }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="发料状态" width="90">
<template slot-scope="scope">
<div :style="getStatusStyle(scope.row.发料状态)" class="score-cell">{{ scope.row.发料状态 }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="装配开工" width="90">
<template slot-scope="scope">
<div :style="getStatusStyle(scope.row.装配开工)" class="score-cell">{{ scope.row.装配开工 }}</div>
</template>
</el-table-column>
<el-table-column align="center" prop="完成数量" label="送检数量" width="90" />
<el-table-column align="center" label="终检" width="70">
<template slot-scope="scope">
<div :style="getStatusStyle(scope.row.终检)" class="score-cell">{{ scope.row.终检 }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="工艺" width="70">
<template slot-scope="scope">
<div :style="getStatusStyle(scope.row.生产工艺)" class="score-cell">{{ scope.row.生产工艺 }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="缺件项" width="80">
<template slot-scope="scope">{{ scope.row.缺件明细.length }}</template>
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<script>
export default {
name: 'TimelyKitTrackingResult',
data() {
return {
orderNo: '',
contractNo: '',
productCode: '',
productName: '',
processName: '',
planNo: '',
shipmentStatus: '全部',
complete: '全部',
checkStatus: '',
sendStatus: '全部',
selfStatus: '全部',
planStart: '',
tableData: [],
loading: false
}
},
created() {
this.searchTable()
},
methods: {
async searchTable() {
this.loading = true
this.tableData = []
const param = []
param.push(['订单号', this.orderNo || 0])
param.push(['物料类型', '自制件'])
param.push(['合同号', this.contractNo])
param.push(['产品编码', this.productCode])
param.push(['产品名称', this.productName])
param.push(['工序名称', this.processName])
param.push(['计划开始', ''])
param.push(['计划完成', this.planStart])
param.push(['排产状态', '全部'])
param.push(['指派对象', '全部'])
param.push(['计划号', this.planNo])
param.push(['发货状态', this.shipmentStatus])
param.push(['齐套', this.complete])
param.push(['检验状态', this.checkStatus])
param.push(['发料状态', this.sendStatus])
param.push(['自制件属性', this.selfStatus])
const data = this.CreateData('11', '生产管理_及时齐套跟踪结果_查询', param)
try {
const response = await this.ExecDatabase(data)
this.tableData = this.mergeRows(response.data || [])
if (this.tableData.length === 0) {
this.$message.info('未查询到及时齐套跟踪结果')
}
} catch (error) {
console.error('及时齐套跟踪结果查询失败:', error)
this.$message.error('查询失败')
} finally {
this.loading = false
}
},
mergeRows(rows) {
const map = new Map()
rows.forEach(row => {
const key = [
row.订单号 || '',
row.合同号 || '',
row.计划号 || '',
row.产品编码 || ''
].join('|')
if (!map.has(key)) {
map.set(key, {
计划号: row.计划号,
合同号: row.合同号,
订单号: row.订单号,
产品编码: row.产品编码,
产品名称: row.产品名称,
计划数量订单: this.formatQuantity(row.计划数量订单),
入库数量: this.formatQuantity(row.入库数量),
要求完工日期: row.要求完工日期,
要求发货日期: row.要求发货日期,
预计齐套时间: row.预计齐套时间,
齐套: row.齐套,
拣配状态: row.拣配状态,
发料状态: row.发料状态,
装配开工: row.装配开工,
完成数量: this.formatQuantity(row.完成数量),
终检: row.终检,
生产工艺: row.生产工艺,
缺件明细: []
})
}
const detailKey = [
row.缺件生产订单号 || '',
row.缺件物料编码 || '',
row.缺件属性 || ''
].join('|')
const current = map.get(key)
if (current.缺件明细.some(item => item.detailKey === detailKey)) {
return
}
current.缺件明细.push({
detailKey,
缺件物料编码: row.缺件物料编码,
缺件物料名称: row.缺件物料名称,
缺件数量: this.formatQuantity(row.缺件数量),
缺件属性: row.缺件属性,
缺件生产订单号: row.缺件生产订单号,
进度: row.进度,
工艺路线: row.工艺路线,
工艺路线明细: this.parseRouteDetails(row.工艺路线明细),
预计完成时间: row.预计完成时间,
采购员: row.采购员,
采购未清数量: this.formatQuantity(row.采购未清数量),
到货草稿: row.到货草稿,
质检状态: row.质检状态,
SAP单据: row.SAP单据,
SAP行号: row.SAP行号
})
})
return Array.from(map.values())
},
detailRowClassName() {
return 'detail-row'
},
parseRouteDetails(value) {
if (!value) return []
if (Array.isArray(value)) return value
try {
const parsed = JSON.parse(value)
return Array.isArray(parsed) ? parsed : []
} catch (error) {
return []
}
},
toProcessNumber(value) {
const num = Number(value)
return Number.isFinite(num) ? num : 0
},
isValidProcessDate(value) {
if (!value) return false
const date = new Date(value)
return !Number.isNaN(date.getTime()) && date > new Date('1900-01-01 00:00:00')
},
getProcessStatusNum(value) {
const num = parseInt(value)
if (Number.isFinite(num)) return num
const statusMap = {
辅助开始: 2,
辅助结束: 3,
开始加工: 4,
暂停: 5,
报工: 6
}
return statusMap[value] || 0
},
isProcessComplete(process) {
const progress = this.toProcessNumber(process.进度)
const planCount = this.toProcessNumber(process.计划数量)
const finishCount = this.toProcessNumber(process.完成数量)
const checkedCount = this.toProcessNumber(process.收检合格数) + this.toProcessNumber(process.收检不合格数)
return progress >= 100 ||
(planCount > 0 && finishCount >= planCount) ||
(planCount > 0 && checkedCount >= planCount)
},
getProcessClass(process, index, processes) {
if (this.isProcessComplete(process)) {
return 'process-route-blue'
}
const statusNum = this.getProcessStatusNum(process.加工状态)
if (this.isValidProcessDate(process.开工时间) || [2, 4].includes(statusNum) || this.toProcessNumber(process.进度) > 0) {
return 'process-route-green'
}
if (index > 0 && this.isProcessComplete(processes[index - 1])) {
return 'process-route-orange'
}
return 'process-route-red'
},
getRouteProcessName(process) {
const name = String(process.工序名称 || '')
const assignee = String(process.指派对象 || '')
if (!assignee || name.includes(`(${assignee})`) || name.includes(`${assignee}`)) {
return name
}
return `${name}(${assignee})`
},
escapeProcessHtml(value) {
return String(value == null ? '' : value)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
},
formatProcessRoute(detail) {
const processes = Array.isArray(detail.工艺路线明细) ? detail.工艺路线明细 : []
if (processes.length === 0) {
return this.escapeProcessHtml(detail.工艺路线 || '')
}
const maxPerRow = 8
const rows = Math.ceil(processes.length / maxPerRow)
let html = '<div class="process-route-wrap"><table class="process-route-table"><tbody>'
for (let rowIndex = 0; rowIndex < rows; rowIndex++) {
const startIndex = rowIndex * maxPerRow
const rowProcesses = processes.slice(startIndex, startIndex + maxPerRow)
if (rowIndex > 0) {
html += `<tr class="process-route-spacer"><td colspan="${maxPerRow * 2 - 1}"></td></tr>`
}
html += '<tr>'
rowProcesses.forEach((process, index) => {
const className = this.getProcessClass(process, startIndex + index, processes)
const date = this.formatDate(process.计划开始时间 || process.计划完成时间)
html += `<td class="process-route-date ${className}">${this.escapeProcessHtml(date)}</td>`
if (index < rowProcesses.length - 1) html += '<td class="process-route-arrow-hidden"></td>'
})
html += '</tr><tr>'
rowProcesses.forEach((process, index) => {
const className = this.getProcessClass(process, startIndex + index, processes)
html += `<td class="${className}">${this.escapeProcessHtml(this.getRouteProcessName(process))}</td>`
if (index < rowProcesses.length - 1) html += '<td class="process-route-arrow">→</td>'
})
html += '</tr><tr>'
rowProcesses.forEach((process, index) => {
const className = this.getProcessClass(process, startIndex + index, processes)
const count = this.formatQuantity(process.收检合格数)
html += `<td class="process-route-count ${className}">合格${this.escapeProcessHtml(count)}</td>`
if (index < rowProcesses.length - 1) html += '<td class="process-route-arrow-hidden"></td>'
})
html += '</tr>'
}
html += '</tbody></table></div>'
return html
},
formatDate(value) {
if (!value) return ''
return String(value).split('T')[0].split(' ')[0]
},
formatQuantity(value) {
if (value === null || value === undefined || value === '') return ''
const numberValue = Number(value)
if (Number.isNaN(numberValue)) return value
return Number.isInteger(numberValue) ? String(numberValue) : String(numberValue).replace(/0+$/, '').replace(/\.$/, '')
},
getStatusStyle(value) {
if (value === '是' || value === '发料齐套' || value === '已拣配' || value === '已开工' || value === '已完成') {
return {
backgroundColor: '#f0f9eb',
color: '#67c23a'
}
}
if (value === '否' || value === '发料缺件' || value === '未拣配' || value === '待执行' || value === '未完成') {
return {
backgroundColor: '#fdf6ec',
color: '#e6a23c'
}
}
return {}
}
}
}
</script>
<style scoped>
.timely-kit-page {
padding: 0;
}
.search-container {
display: flex;
flex-wrap: wrap;
gap: 8px 0;
}
.show-text {
line-height: 32px;
margin-right: 5px;
white-space: nowrap;
}
.filter-control {
margin-right: 10px;
width: 150px;
}
.small-filter {
margin-right: 10px;
width: 100px;
}
.score-cell {
border-radius: 3px;
padding: 2px 4px;
}
.detail-table {
margin: 4px 0;
}
.purchase-route {
line-height: 22px;
text-align: left;
white-space: normal;
}
.process-route {
overflow-x: auto;
padding: 2px 0;
}
::v-deep .process-route-wrap {
min-width: 480px;
}
::v-deep .process-route-table {
border-collapse: separate;
border-spacing: 0;
margin: 0 auto;
}
::v-deep .process-route-table td {
border-radius: 2px;
line-height: 20px;
min-width: 72px;
padding: 2px 5px;
text-align: center;
white-space: nowrap;
}
::v-deep .process-route-date,
::v-deep .process-route-count {
font-size: 12px;
}
::v-deep .process-route-arrow,
::v-deep .process-route-arrow-hidden {
background: transparent;
color: #606266;
min-width: 18px;
width: 18px;
}
::v-deep .process-route-arrow-hidden {
color: transparent;
}
::v-deep .process-route-spacer td {
height: 6px;
line-height: 6px;
padding: 0;
}
::v-deep .process-route-green {
background: #f0f9eb;
color: #67c23a;
}
::v-deep .process-route-blue {
background: #ecf5ff;
color: #409eff;
}
::v-deep .process-route-orange {
background: #fdf6ec;
color: #e6a23c;
}
::v-deep .process-route-red {
background: #fef0f0;
color: #f56c6c;
}
::v-deep .detail-row td {
background-color: #f0f9eb !important;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -399,7 +399,7 @@
>
检验记录
</div> -->
<!-- <div class="grid-btn" style="margin-left: 50px" @click="Abnormalcontrol()">异常管控</div> -->
<div class="grid-btn" style="margin-left: 50px" @click="Abnormalcontrol()">异常管控</div>
<div
class="grid-btn"
style="margin-left: 50px"
@@ -1275,6 +1275,15 @@
<el-button type="primary" @click="abnormalForm()"> </el-button>
</div>
</el-dialog>
<el-dialog
:visible.sync="abnormalControlDialogVisible"
title="异常管控"
width="1200px"
center
append-to-body
:close-on-click-modal="false">
<abnormal-control-panel :initial-selected-row="selectedRow" />
</el-dialog>
<el-dialog
:visible.sync="addRecordDialogVisible"
title="新增工时记录"
@@ -1841,7 +1850,11 @@ import { MESDownFile } from '@/utils/request'
import { postB1 } from '@/api/b1s';
import { getB1 } from '@/api/b1s';
import { posttm } from '@/api/tm';
import AbnormalControlPanel from '@/views/ProductionManagement/components/AbnormalControlPanel.vue';
export default {
components: {
AbnormalControlPanel
},
data() {
return {
TaskAID: "",
@@ -2015,6 +2028,7 @@ export default {
currentInspectionRecord: {}, // 当前选中的检验记录
abnormalControlDialogVisible: false,
//异常管控相关数据
orderNo: '',
contractNo: '',
@@ -3479,6 +3493,9 @@ async workendForm() {
this.abnormalVisible = true;
this.abnormalTable();
},
Abnormalcontrol() {
this.abnormalControlDialogVisible = true;
},
abnormalTable() {
var param = [];
param.push(["操作人", this.$store.state.user.name]);

View File

@@ -2131,6 +2131,15 @@
</el-button>
</div>
</el-dialog>
<el-dialog
:visible.sync="abnormalControlDialogVisible"
title="异常管控"
width="1200px"
center
append-to-body
:close-on-click-modal="false">
<abnormal-control-panel :initial-selected-row="selectedRow" />
</el-dialog>
<el-dialog :visible.sync="Abnormalcontrolpop"
title="异常管控"
width="1200px"
@@ -2271,9 +2280,6 @@
<el-input type="textarea" v-model="newProcessForm.description" :rows="3"
placeholder="请输入流程详细描述"></el-input>
</el-form-item>
<el-form-item label="上传附件" prop="title">
<el-button type="primary" icon="el-icon-circle-plus-outline" size="small" @click="uploadShowPDF" style="width: 100px;">点击上传</el-button>
</el-form-item>
<!-- 审批流程设置 -->
<div class="form-section" v-if="newProcessForm.type">
<div class="form-section-title">
@@ -2327,7 +2333,7 @@
<el-table v-loading="loading" :data="tableData5" :height="'40vh'" border
element-loading-background="rgba(0, 0, 0, 0.2)" element-loading-spinner="el-icon-loading"
highlight-current-row size="mini" style="width: 100%;" tooltip-effect="dark"
@row-click="handleRowClick">
@row-click="handleAbnormalControlTaskRowClick">
<!-- <el-table-column align="center" label="序号" type="index" width="50" fixed /> -->
<el-table-column align="center" prop="产品名称" label="物料名称" width="190" fixed/>
@@ -2492,23 +2498,6 @@
<el-button type="primary" @click="confirmComplete" :loading="completeLoading" style="width: auto;"> </el-button>
</span>
</el-dialog>
<!--上传文件-->
<!-- <el-dialog :visible.sync="imgDialogFormVisible" title="上传附件" center width="460px">
<el-upload
ref="uploadPDF"
:multiple="true"
:auto-upload="false"
style="margin-left: 30px"
drag>
<i class="el-icon-upload"/>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div slot="tip" class="el-upload__tip">上传文件且不超过100mb</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button @click="imgDialogFormVisible=false">取消</el-button>
<el-button type="primary" style="width: 70px" @click="submitPicturePDF()">确定</el-button>
</div>
</el-dialog> -->
<!-- 退库弹窗 -->
<el-dialog
:visible.sync="ReturnWarehousepop"
@@ -2803,7 +2792,11 @@ import { postB1 } from '@/api/b1s';
import { getB1 } from '@/api/b1s';
import { posttm } from '@/api/tm';
import { seepdf, initPDFKeyboardShortcuts, setZoom } from '@/utils/pdf';
import AbnormalControlPanel from '@/views/ProductionManagement/components/AbnormalControlPanel.vue';
export default {
components: {
AbnormalControlPanel
},
data() {
return {
TaskAID:'',
@@ -2973,6 +2966,7 @@ export default {
currentInspectionRecord: {}, // 当前选中的检验记录
abnormalControlDialogVisible: false,
//异常管控相关数据
orderNo: '',
contractNo: '',
@@ -2990,8 +2984,6 @@ export default {
tableProcessName: '',
selectedRow: '',
loading: false,
imgDialogFormVisible: false,
// 转办相关数据
transferDialogVisible: false,
transferLoading: false,
@@ -3160,11 +3152,7 @@ export default {
this.getTypeList();
this.getOperationPersonList();
this.searchTable4();
this.searchTable1();
this.getUserList();
this.getProcessedTasks();
this.initPauseState()
this.loadOrderList('')
this.getBind()
@@ -4043,20 +4031,23 @@ confirmOvertime() {
// ⭐ 直接弹出加班确认弹窗
overtimeResult = await this.showOvertimeDialog()
if (overtimeResult && overtimeResult.persons && overtimeResult.persons.length > 0) {
// 添加调机人员到加班人员列表
const allOvertimePersons = [...overtimeResult.persons]
if (this.selectedOperatorsName && !allOvertimePersons.includes(this.selectedOperatorsName)) {
allOvertimePersons.push(this.selectedOperatorsName)
}
ordinaryPersons = overtimeResult.ordinaryPersons ? overtimeResult.ordinaryPersons.join(',') : ''
specialPersons = overtimeResult.specialPersons ? overtimeResult.specialPersons.join(',') : ''
if (overtimeResult) {
isOvertime = overtimeResult.isOvertime || 0
isRestDay = overtimeResult.isRestDay || 0
isLegalRestDay = overtimeResult.isLegalRestDay || 0
selectedShiftName = overtimeResult.selectedShift || this.shift
shiftStandardHours = this.shiftStandardHours || 0
shiftStandardHours = overtimeResult.shiftStandardHours || this.shiftStandardHours || 0
if (overtimeResult.persons && overtimeResult.persons.length > 0) {
// 添加调机人员到加班人员列表
const allOvertimePersons = [...overtimeResult.persons]
if (this.selectedOperatorsName && !allOvertimePersons.includes(this.selectedOperatorsName)) {
allOvertimePersons.push(this.selectedOperatorsName)
}
ordinaryPersons = overtimeResult.ordinaryPersons ? overtimeResult.ordinaryPersons.join(',') : ''
specialPersons = overtimeResult.specialPersons ? overtimeResult.specialPersons.join(',') : ''
}
} else if (overtimeResult === null || overtimeResult === undefined) {
// 用户关闭了弹窗,询问是否继续
const continueReport = await this.$confirm('未记录加班信息,是否继续辅助结束?', '提示', {
@@ -4447,15 +4438,18 @@ async proReportForm() {
// 每次都弹出加班确认弹框
overtimeResult = await this.showOvertimeDialog()
if (overtimeResult && overtimeResult.persons && overtimeResult.persons.length > 0) {
overtimePersons = overtimeResult.persons.join(',') // 所有人员
ordinaryPersons = overtimeResult.ordinaryPersons.join(',') // 普通人员
specialPersons = overtimeResult.specialPersons.join(',') // 特殊人员
if (overtimeResult) {
isOvertime = overtimeResult.isOvertime
isRestDay = overtimeResult.isRestDay
isLegalRestDay = overtimeResult.isLegalRestDay
selectedShiftName = overtimeResult.selectedShift || this.shift
shiftStandardHours = this.shiftStandardHours || 8
shiftStandardHours = overtimeResult.shiftStandardHours || this.shiftStandardHours || 8
if (overtimeResult.persons && overtimeResult.persons.length > 0) {
overtimePersons = overtimeResult.persons.join(',') // 所有人员
ordinaryPersons = overtimeResult.ordinaryPersons ? overtimeResult.ordinaryPersons.join(',') : '' // 普通人员
specialPersons = overtimeResult.specialPersons ? overtimeResult.specialPersons.join(',') : '' // 特殊人员
}
} else if (overtimeResult === null || overtimeResult === undefined) {
// 用户关闭了弹窗,询问是否继续
const continueReport = await this.$confirm('未记录加班信息,是否继续报工?', '提示', {
@@ -6047,21 +6041,6 @@ async proReportForm() {
//异常管控相关函数
uploadShowPDF(val) {
this.imgDialogFormVisible = true
},
submitPicturePDF() {
// 修改这里:确保参数名与后台一致
this.DataPDF = {
num: this.uploadValue, // 取消注释,使用实际值
tableName: '流程表',
worker: this.$store.state.user.name, // 取消注释
uploadTime: this.currentTime // 取消注释
}
console.log('上传参数:', JSON.stringify(this.DataPDF))
this.$refs.uploadPDF.submit()
this.imgDialogFormVisible = false
},
getProcessedTasks() {
var params = []
params.push(['审批人ID', this.$store.state.user.id])
@@ -6202,7 +6181,7 @@ async proReportForm() {
},
// 数据处理方法
handleRowClick(row) {
handleAbnormalControlTaskRowClick(row) {
this.selectedRow = row
this.tableOrderNum = row.订单号
this.tableProductCode = row.物料编码
@@ -6423,7 +6402,7 @@ submitNewProcess() {
return new Date(deadline) - new Date() < 24 * 60 * 60 * 1000;
},
Abnormalcontrol(){
this.Abnormalcontrolpop = true
this.abnormalControlDialogVisible = true
},
ReturnWarehouse(){
this.ReturnWarehousepop = true

View File

@@ -0,0 +1,298 @@
<template>
<div class="settlement-workhours">
<el-card>
<div class="search-container">
<span class="show-text">生产订单号:</span>
<el-input v-model="searchForm.orderNo" placeholder="请输入生产订单号" clearable style="width: 140px; margin-right: 10px" />
<span class="show-text">物料编码:</span>
<el-input v-model="searchForm.productCode" placeholder="请输入物料编码" clearable style="width: 160px; margin-right: 10px" />
<span class="show-text">工位:</span>
<el-input v-model="searchForm.station" placeholder="请输入工位" clearable style="width: 120px; margin-right: 10px" />
<span class="show-text">数据条数:</span>
<el-input v-model="searchForm.datanum" placeholder="数据条数" clearable style="width: 100px; margin-right: 10px" />
<span class="show-text">开始日期:</span>
<el-date-picker
v-model="searchForm.startDate"
type="date"
placeholder="选择开始日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
style="width: 150px; margin-right: 10px" />
<span class="show-text">结束日期:</span>
<el-date-picker
v-model="searchForm.endDate"
type="date"
placeholder="选择结束日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
style="width: 150px; margin-right: 10px" />
<el-button :loading="loading" icon="el-icon-search" plain type="primary" @click="handleSearch">查询</el-button>
</div>
<el-table
v-loading="loading"
:data="tableData"
:height="tableHeight"
border
size="mini"
row-key="id"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
default-expand-all
class="custom-tree-table"
:row-class-name="tableRowClassName"
style="width: 100%">
<el-table-column prop="taskDescription" label="任务描述" min-width="380" show-overflow-tooltip>
<template slot-scope="scope">
<span :class="{ 'bold-text': scope.row.level === 1 }">{{ scope.row.taskDescription || '' }}</span>
</template>
</el-table-column>
<el-table-column prop="productionOrderNo" label="生产订单号" width="130" align="center" show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.productionOrderNo || '' }}
</template>
</el-table-column>
<el-table-column prop="station" label="工位" width="110" align="center" show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.station || '' }}
</template>
</el-table-column>
<el-table-column prop="reportWorkHours" label="报工工时" width="100" align="center">
<template slot-scope="scope">
<span :class="{ 'bold-text': scope.row.level <= 2 }">{{ scope.row.reportWorkHours || '' }}</span>
</template>
</el-table-column>
<el-table-column prop="auxiliaryWorkHours" label="主辅工时" width="100" align="center">
<template slot-scope="scope">
<span :class="{ 'bold-text': scope.row.level <= 2 }">{{ scope.row.auxiliaryWorkHours || '' }}</span>
</template>
</el-table-column>
<el-table-column prop="reportFinishQty" label="报工完成数" width="110" align="center">
<template slot-scope="scope">
<span :class="{ 'bold-text': scope.row.level <= 2 }">{{ scope.row.reportFinishQty || '' }}</span>
</template>
</el-table-column>
<el-table-column prop="auxiliaryFinishQty" label="辅助完成数" width="110" align="center">
<template slot-scope="scope">
<span :class="{ 'bold-text': scope.row.level <= 2 }">{{ scope.row.auxiliaryFinishQty || '' }}</span>
</template>
</el-table-column>
<el-table-column prop="totalWorkHours" label="合计工时" width="100" align="center">
<template slot-scope="scope">
<span :class="{ 'bold-text': scope.row.level <= 2 }">{{ scope.row.totalWorkHours || '' }}</span>
</template>
</el-table-column>
<el-table-column prop="clampingTime" label="装夹时间" width="100" align="center">
<template slot-scope="scope">
{{ scope.row.clampingTime || '' }}
</template>
</el-table-column>
<el-table-column prop="programTime" label="程序时间" width="100" align="center">
<template slot-scope="scope">
{{ scope.row.programTime || '' }}
</template>
</el-table-column>
<el-table-column prop="settlementReportPieceHours" label="结算报工单件工时" width="140" align="center">
<template slot-scope="scope">
{{ scope.row.settlementReportPieceHours || '' }}
</template>
</el-table-column>
<el-table-column prop="settlementAuxiliaryPieceHours" label="结算辅助单件工时" width="140" align="center">
<template slot-scope="scope">
{{ scope.row.settlementAuxiliaryPieceHours || '' }}
</template>
</el-table-column>
<el-table-column prop="operatorNames" label="操作人" width="180" align="center" show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.operatorNames || '' }}
</template>
</el-table-column>
</el-table>
<div class="summary-footer">
<span>报工工时<strong>{{ totals.reportWorkHours }}</strong> 小时 | 主辅工时<strong>{{ totals.auxiliaryWorkHours }}</strong> 小时 | 合计工时<strong>{{ totals.totalWorkHours }}</strong> 小时</span>
</div>
</el-card>
</div>
</template>
<script>
export default {
name: 'SettlementWorkhours',
data() {
return {
searchForm: {
contractNo: '',
productCode: '',
orderNo: '',
station: '',
startDate: '',
endDate: '',
datanum: 100
},
loading: false,
tableHeight: '68vh',
tableData: []
}
},
computed: {
totals() {
const totals = this.tableData.reduce((sum, row) => {
sum.reportWorkHours += this.parseNumber(row.reportWorkHours)
sum.auxiliaryWorkHours += this.parseNumber(row.auxiliaryWorkHours)
sum.totalWorkHours += this.parseNumber(row.totalWorkHours)
return sum
}, {
reportWorkHours: 0,
auxiliaryWorkHours: 0,
totalWorkHours: 0
})
return {
reportWorkHours: totals.reportWorkHours.toFixed(2),
auxiliaryWorkHours: totals.auxiliaryWorkHours.toFixed(2),
totalWorkHours: totals.totalWorkHours.toFixed(2)
}
}
},
methods: {
parseNumber(value) {
const numberValue = Number(value)
return Number.isFinite(numberValue) ? numberValue : 0
},
handleSearch() {
this.loadData()
},
loadData() {
this.loading = true
const param = [
['合同号', this.searchForm.contractNo || ''],
['产品编码', this.searchForm.productCode || ''],
['订单号', this.searchForm.orderNo || ''],
['工位', this.searchForm.station || ''],
['开始日期', this.searchForm.startDate || ''],
['结束日期', this.searchForm.endDate || ''],
['数据条数', this.searchForm.datanum || '']
]
const Data = this.CreateData('11', '生产管理_结算工时_查询', param)
this.ExecDatabase(Data).then(res => {
this.tableData = this.buildTree(res.data || [])
this.loading = false
}).catch(() => {
this.loading = false
})
},
buildTree(flatData) {
const materialMap = new Map()
flatData.forEach((row, index) => {
if (Number(row.Level) !== 1) return
materialMap.set(row.materialCode, {
id: `m-${index}`,
level: 1,
materialCode: row.materialCode,
materialDesc: row.materialDesc,
taskDescription: row.taskDescription,
reportWorkHours: row.reportWorkHours,
auxiliaryWorkHours: row.auxiliaryWorkHours,
reportFinishQty: row.reportFinishQty,
auxiliaryFinishQty: row.auxiliaryFinishQty,
totalWorkHours: row.totalWorkHours,
clampingTime: row.clampingTime,
programTime: row.programTime,
settlementReportPieceHours: row.settlementReportPieceHours,
settlementAuxiliaryPieceHours: row.settlementAuxiliaryPieceHours,
recordCount: row.recordCount,
children: []
})
})
flatData.forEach((row, index) => {
if (Number(row.Level) !== 2) return
const parent = materialMap.get(row.materialCode)
if (!parent) return
parent.children.push({
id: `o-${index}`,
level: 2,
materialCode: row.materialCode,
materialDesc: row.materialDesc,
taskDescription: row.taskDescription,
productionOrderNo: row.productionOrderNo,
station: row.station,
reportWorkHours: row.reportWorkHours,
auxiliaryWorkHours: row.auxiliaryWorkHours,
reportFinishQty: row.reportFinishQty,
auxiliaryFinishQty: row.auxiliaryFinishQty,
totalWorkHours: row.totalWorkHours,
clampingTime: row.clampingTime,
programTime: row.programTime,
settlementReportPieceHours: row.settlementReportPieceHours,
settlementAuxiliaryPieceHours: row.settlementAuxiliaryPieceHours,
operatorNames: row.operatorNames,
recordCount: row.recordCount
})
})
return Array.from(materialMap.values())
},
tableRowClassName({ row }) {
if (row.level === 1) return 'material-row'
return ''
}
}
}
</script>
<style scoped>
.settlement-workhours {
padding: 10px;
}
.search-container {
margin-bottom: 10px;
display: flex;
align-items: center;
flex-wrap: wrap;
}
.show-text {
margin-right: 5px;
font-size: 14px;
color: #606266;
}
.bold-text {
font-weight: 700;
color: #303133;
}
::v-deep .el-table .material-row {
background: #f5f7fa !important;
}
::v-deep .el-table .material-row:hover > td {
background-color: #f5f7fa !important;
}
.summary-footer {
margin-top: 10px;
padding: 10px;
background: #f5f7fa;
border: 1px solid #ebeef5;
border-radius: 4px;
font-size: 14px;
color: #606266;
}
</style>

View File

@@ -563,6 +563,108 @@ export default {
getWorkHoursType(row) {
return row.工时类型 || row.workType || row.WorkType || row.workHoursType || row.WorkHoursType || '未分类'
},
getStartTimeValue(row) {
if (!row) return Number.MAX_SAFE_INTEGER
const value = row.startTime || row.planStart || row.开始时间 || row.dateLabel || ''
const text = String(value).trim()
if (!text) return Number.MAX_SAFE_INTEGER
const normalizedText = text.includes('T') ? text : text.replace(/-/g, '/')
const time = new Date(normalizedText).getTime()
return Number.isNaN(time) ? Number.MAX_SAFE_INTEGER : time
},
getEarliestStartTime(row) {
if (row && Array.isArray(row.children) && row.children.length > 0) {
return Math.min(...row.children.map(child => this.getEarliestStartTime(child)))
}
return this.getStartTimeValue(row)
},
sortRowsByStartTime(rows) {
return (rows || []).map(row => {
if (Array.isArray(row.children) && row.children.length > 0) {
row.children = this.sortRowsByStartTime(row.children)
}
return row
}).sort((a, b) => {
const diff = this.getEarliestStartTime(a) - this.getEarliestStartTime(b)
if (diff !== 0) return diff
return String(a.id || '').localeCompare(String(b.id || ''), 'zh-CN')
})
},
parseReportQty(value) {
const sourceValue = value === null || value === undefined ? 0 : value
const qty = Number(String(sourceValue).replace(/,/g, ''))
return Number.isFinite(qty) ? qty : 0
},
formatReportQty(value) {
if (!Number.isFinite(value)) return '0'
return Number.isInteger(value) ? String(value) : String(Number(value.toFixed(6)))
},
getTaskAID(row) {
if (!row) return ''
return row.TaskAID || row.taskAID || row.TaskId || row.taskId || row.任务ID || row.AID || ''
},
getReportQtyGroupKey(row) {
const taskAID = this.getTaskAID(row)
const startTime = row && (row.startTime || row.开始时间 || '')
if (!taskAID || !startTime) return ''
return `${taskAID}_${startTime}`
},
isAssemblyAssignee(row) {
const assignee = row && (row.指派对象 || row.工位名称 || row.assignee || '')
return String(assignee).includes('装配')
},
buildTaskStartReportQtyMap(rows) {
const qtyMap = new Map()
;(rows || []).forEach(row => {
if (Number(row.Level) !== 3) return
const key = this.getReportQtyGroupKey(row)
if (!key) return
const reportQty = row.reportQty === null || row.reportQty === undefined ? row.报工数量 : row.reportQty
const qty = this.parseReportQty(reportQty)
const current = qtyMap.has(key) ? qtyMap.get(key) : Number.NEGATIVE_INFINITY
qtyMap.set(key, Math.max(current, qty))
})
return qtyMap
},
getTaskStartReportQty(row, qtyMap) {
if (this.isAssemblyAssignee(row)) return '0'
const key = this.getReportQtyGroupKey(row)
if (!key || !qtyMap || !qtyMap.has(key)) return row.reportQty
return this.formatReportQty(qtyMap.get(key))
},
recalculateOperatorReportQty(treeData) {
;(treeData || []).forEach(operator => {
const operatorQtyMap = new Map()
let operatorHasTaskStartKey = false
;(operator.children || []).forEach(date => {
const dateQtyMap = new Map()
let dateHasTaskStartKey = false
;(date.children || []).forEach(detail => {
const key = detail.reportQtyGroupKey
if (!key) return
const qty = this.parseReportQty(detail.reportQty)
dateHasTaskStartKey = true
operatorHasTaskStartKey = true
const currentDateQty = dateQtyMap.has(key) ? dateQtyMap.get(key) : Number.NEGATIVE_INFINITY
const currentOperatorQty = operatorQtyMap.has(key) ? operatorQtyMap.get(key) : Number.NEGATIVE_INFINITY
dateQtyMap.set(key, Math.max(currentDateQty, qty))
operatorQtyMap.set(key, Math.max(currentOperatorQty, qty))
})
if (dateHasTaskStartKey) {
const dateQty = Array.from(dateQtyMap.values()).reduce((sum, qty) => sum + qty, 0)
date.reportQty = this.formatReportQty(dateQty)
}
})
if (operatorHasTaskStartKey) {
const operatorQty = Array.from(operatorQtyMap.values()).reduce((sum, qty) => sum + qty, 0)
operator.reportQty = this.formatReportQty(operatorQty)
}
})
},
getCurrentSummaryItems() {
const items = []
if (this.activeTab === 'project') {
@@ -684,7 +786,7 @@ export default {
}
})
return Array.from(level1Map.values())
return this.sortRowsByStartTime(Array.from(level1Map.values()))
},
loadOperatorData() {
@@ -702,7 +804,7 @@ export default {
const Data = this.CreateData('11', '工时统计_作业者工时_查询', param)
this.ExecDatabase(Data).then(res => {
this.operatorTableData = this.buildOperatorTree(res.data || [])
this.operatorTableData = this.buildOperatorTree(res.data || [], true)
this.loading = false
}).catch(() => {
this.loading = false
@@ -730,9 +832,10 @@ export default {
})
},
buildOperatorTree(flatData) {
buildOperatorTree(flatData, useTaskStartMaxReportQty = false) {
const level1Map = new Map()
const level2Map = new Map()
const reportQtyMap = useTaskStartMaxReportQty ? this.buildTaskStartReportQtyMap(flatData) : null
flatData.forEach((row, index) => {
if (row.Level === 1) {
@@ -761,9 +864,13 @@ export default {
const key = `${row.operator}_${row.dateLabel}`
const parent = level2Map.get(key)
if (parent) {
const taskAID = this.getTaskAID(row)
const reportQtyGroupKey = this.getReportQtyGroupKey(row)
const reportQty = useTaskStartMaxReportQty ? this.getTaskStartReportQty(row, reportQtyMap) : row.reportQty
parent.children.push({
id: `o-${index}`,
level: 3,
TaskAID: taskAID,
contractNo: row.contractNo,
orderNo: row.orderNo,
productCode: row.productCode,
@@ -775,7 +882,8 @@ export default {
班次: row.班次,
报工类型: row.报工类型,
指派对象: row.指派对象,
reportQty: row.reportQty,
reportQty,
reportQtyGroupKey,
startTime: row.startTime,
endTime: row.endTime,
workHours: row.workHours,
@@ -794,7 +902,11 @@ export default {
}
})
return Array.from(level1Map.values())
const treeData = this.sortRowsByStartTime(Array.from(level1Map.values()))
if (useTaskStartMaxReportQty) {
this.recalculateOperatorReportQty(treeData)
}
return treeData
},
loadTaskData() {
@@ -872,7 +984,7 @@ export default {
}
})
return Array.from(level1Map.values())
return this.sortRowsByStartTime(Array.from(level1Map.values()))
},
tableRowClassName({ row }) {

View File

@@ -45,60 +45,77 @@
:row-class-name="tableRowClassName"
style="width: 100%">
<el-table-column prop="taskAID" label="任务描述" width="500" show-overflow-tooltip>
<el-table-column prop="taskDescription" label="任务描述" width="360" show-overflow-tooltip>
<template slot-scope="scope">
<span :class="{'bold-text': scope.row.level === 1}">
{{ scope.row.level === 1 ? scope.row.taskAID :
scope.row.level === 2 ? scope.row.dateLabel :
scope.row.level === 3 ? `${scope.row.dateLabel} (${scope.row.shift})` : '' }}
{{ scope.row.level === 1 ? scope.row.taskDescription : '' }}
</span>
</template>
</el-table-column>
<!-- <el-table-column prop="reportCount" label="报工次数" width="80" align="center">
<el-table-column prop="dateLabel" label="日期" width="130" align="center" show-overflow-tooltip>
<template slot-scope="scope">
<span :class="{'bold-text': scope.row.level <= 2}">{{ scope.row.reportCount || '' }}</span>
<span :class="{'bold-text': scope.row.level === 2}">
{{ scope.row.level === 2 ? `日期${scope.row.dateLabel || ''}` : scope.row.dateLabel || '' }}
</span>
</template>
</el-table-column> -->
</el-table-column>
<el-table-column prop="shift" label="班次" width="100" align="center" show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.shift || '' }}
</template>
</el-table-column>
<el-table-column prop="operatorNames" label="操作人" width="160" align="center" show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.operatorNames || '' }}
</template>
</el-table-column>
<el-table-column prop="productionOrderNo" label="生产订单号" width="140" align="center" show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.productionOrderNo || '' }}
</template>
</el-table-column>
<el-table-column prop="reportType" label="报工类型" width="110" align="center" show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.reportType || '' }}
</template>
</el-table-column>
<el-table-column prop="reportQty" label="报工数量" width="90" align="center">
<template slot-scope="scope">
<span :class="{'bold-text': scope.row.level <= 2}">{{ scope.row.reportQty || '' }}</span>
</template>
</el-table-column>
<el-table-column prop="工位名称" label="工位名称" width="90" align="center">
<el-table-column prop="station" label="工位" width="90" align="center" show-overflow-tooltip>
<template slot-scope="scope">
<span :class="{'bold-text': scope.row.level <= 2}">{{ scope.row.工位名称 || '' }}</span>
{{ scope.row.station || '' }}
</template>
</el-table-column>
<el-table-column prop="actualWorkHours" label="实际工时" width="90" align="center">
<el-table-column prop="workHours" label="工时" width="90" align="center">
<template slot-scope="scope">
{{ scope.row.actualWorkHours || '' }}
<span :class="{'bold-text': scope.row.level <= 2}">{{ scope.row.workHours || '' }}</span>
</template>
</el-table-column>
<el-table-column prop="auxiliaryWorkHours" label="辅助工时" width="90" align="center">
<el-table-column prop="programTime" label="程序时间" width="100" align="center">
<template slot-scope="scope">
{{ scope.row.auxiliaryWorkHours || '' }}
{{ scope.row.programTime || '' }}
</template>
</el-table-column>
<el-table-column prop="avgActualWorkHours" label="平均程序工时" width="100" align="center">
<el-table-column prop="pieceWorkHours" label="单件工时" width="110" align="center">
<template slot-scope="scope">
{{ scope.row.pieceWorkHours || '' }}
</template>
</el-table-column>
<el-table-column prop="avgActualWorkHours" label="平均实际工时" width="100" align="center">
<template slot-scope="scope">
{{ scope.row.avgActualWorkHours || '' }}
</template>
</el-table-column>
<el-table-column prop="avgAuxiliaryWorkHours" label="平均辅助工时" width="100" align="center">
<template slot-scope="scope">
{{ scope.row.avgAuxiliaryWorkHours || '' }}
</template>
</el-table-column>
<el-table-column prop="avgAuxiliaryWorkHours" label="工艺工时" width="100" align="center">
<el-table-column prop="processWorkHours" label="工艺工时" width="100" align="center">
<template slot-scope="scope">
{{ scope.row.processWorkHours || '' }}
</template>
@@ -140,8 +157,7 @@
<!-- 底部汇总 -->
<div class="summary-footer">
<span>实际工时<strong>{{ currentTotalActualHours }}</strong> 小时 |
总辅助工时<strong>{{ currentTotalAuxiliaryHours }}</strong> 小时</span>
<span>总工时<strong>{{ currentTotalWorkHours }}</strong> 小时</span>
</div>
</el-card>
</div>
@@ -181,15 +197,9 @@ export default {
},
computed: {
// 计算当前Tab的总工时
currentTotalActualHours() {
currentTotalWorkHours() {
const total = this.processTableData.reduce((sum, item) => {
return sum + (parseFloat(item.actualWorkHours) || 0)
}, 0)
return total.toFixed(1)
},
currentTotalAuxiliaryHours() {
const total = this.processTableData.reduce((sum, item) => {
return sum + (parseFloat(item.auxiliaryWorkHours) || 0)
return sum + (parseFloat(item.workHours) || 0)
}, 0)
return total.toFixed(1)
}
@@ -224,6 +234,12 @@ export default {
handleTabChange() {
this.loadProcessData()
},
formatReportType(value) {
const reportType = String(value || '')
if (reportType.includes('辅助')) return '调机'
if (reportType.includes('报工')) return '正常'
return reportType
},
loadProcessData() {
this.loading = true
@@ -254,13 +270,13 @@ export default {
level1Map.set(row.TaskAID, {
id: `p1-${index}`,
level: 1,
taskAID: row.taskDescription,
TaskAID: row.TaskAID,
taskDescription: row.taskDescription,
reportCount: row.reportCount,
reportQty: '',
actualWorkHours: row.actualWorkHours,
auxiliaryWorkHours: row.auxiliaryWorkHours,
avgActualWorkHours: row.avgActualWorkHours,
avgAuxiliaryWorkHours: row.avgAuxiliaryWorkHours,
reportQty: row.reportQty,
workHours: row.workHours || row.actualWorkHours,
pieceWorkHours: row.pieceWorkHours,
processWorkHours: row.processWorkHours,
children: []
})
} else if (row.Level === 2) {
@@ -269,46 +285,45 @@ export default {
level2Map.set(key, {
id: `p2-${index}`,
level: 2,
taskAID: row.TaskAID,
TaskAID: row.TaskAID,
taskDescription: row.taskDescription,
dateLabel: row.dateLabel,
shift: '',
operatorNames: '',
productionOrderNo: '',
reportType: '',
reportCount: row.reportCount,
reportQty: '',
actualWorkHours: '',
auxiliaryWorkHours: '',
avgActualWorkHours: row.avgActualWorkHours,
avgAuxiliaryWorkHours: row.avgAuxiliaryWorkHours,
contractNo: '',
orderNo: '',
productCode: '',
productName: '',
processName: '',
reportQty: row.reportQty,
station: '',
workHours: row.workHours || row.actualWorkHours,
programTime: '',
pieceWorkHours: row.pieceWorkHours,
processWorkHours: row.processWorkHours,
startTime: '',
children: []
})
} else if (row.Level === 3) {
// 第三层:按TaskAID、日期和班次汇总
// 第三层:明细
const parentKey = `${row.TaskAID}_${row.dateLabel}`
const parent = level2Map.get(parentKey)
if (parent) {
parent.children.push({
id: `p3-${index}`,
level: 3,
taskAID: row.taskDescription,
TaskAID: row.TaskAID,
taskDescription: row.taskDescription,
dateLabel: row.dateLabel,
shift: row.shift,
reportCount: row.reportCount,
operatorNames: row.operatorNames,
productionOrderNo: row.productionOrderNo,
reportType: this.formatReportType(row.reportType),
reportQty: row.reportQty,
actualWorkHours: row.actualWorkHours,
auxiliaryWorkHours: row.auxiliaryWorkHours,
avgActualWorkHours: row.avgActualWorkHours,
avgAuxiliaryWorkHours: row.avgAuxiliaryWorkHours,
contractNo: row.contractNo,
orderNo: row.orderNo,
productCode: row.productCode,
productName: row.productName,
processName: row.processName,
processWorkHours:row.processWorkHours,
工位名称:row.工位名称,
station: row.station || row.工位名称,
workHours: row.workHours || row.actualWorkHours,
programTime: row.programTime,
pieceWorkHours: row.pieceWorkHours,
processWorkHours: row.processWorkHours,
startTime: row.startTime
})
}
}
@@ -316,7 +331,7 @@ export default {
// 构建树形结构
level2Map.forEach(l2Item => {
const parent = level1Map.get(l2Item.taskAID)
const parent = level1Map.get(l2Item.TaskAID)
if (parent) {
parent.children.push(l2Item)
}
@@ -410,4 +425,4 @@ export default {
::v-deep .el-table__expand-icon {
color: #606266;
}
</style>
</style>

View File

@@ -0,0 +1,994 @@
<template>
<div class="abnormal-control-panel">
<div class="workflow-container">
<!-- 统计信息 -->
<el-row :gutter="20" style="margin-bottom: 20px;">
<el-col :span="8">
<el-card class="stats-card" @click.native="switchTab('pending')">
<div class="stats-number">{{ stats.pending }}</div>
<div class="stats-label">待处理任务</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card class="stats-card" @click.native="switchTab('initiated')">
<div class="stats-number">{{ stats.initiated }}</div>
<div class="stats-label">我发起的</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card class="stats-card" @click.native="switchTab('processed')">
<div class="stats-number">{{ stats.completed }}</div>
<div class="stats-label">已完成</div>
</el-card>
</el-col>
</el-row>
<!-- 选项卡切换 -->
<el-tabs v-model="activeTab" type="border-card" class="workflow-tabs" @tab-click="handleTabClick">
<!-- 待我处理 -->
<el-tab-pane label="待我处理" name="pending">
<div class="filter-bar">
<el-input placeholder="搜索流程名称" v-model="filters.pending.keyword" class="filter-item" style="width: 200px;" clearable>
<el-button slot="append" icon="el-icon-search"></el-button>
</el-input>
<el-select v-model="filters.pending.priority" placeholder="优先级" class="filter-item" clearable>
<el-option label="紧急" value="urgent"></el-option>
<el-option label="高" value="high"></el-option>
<el-option label="普通" value="normal"></el-option>
</el-select>
</div>
<div v-if="filteredPendingTasks.length > 0">
<el-card v-for="task in filteredPendingTasks" :key="task.节点ID" class="process-card">
<div slot="header" class="clearfix">
<el-tag :type="getPriorityType(task.优先级)" class="priority-tag">
{{ getPriorityText(task.优先级) }}
</el-tag>
<span v-if="task.是否转办" class="node-status status-transferred">转办</span>
<el-button style="float: right; padding: 3px 0" type="text" @click="handleTask(task)">处理</el-button>
<el-button size="mini" icon="el-icon-s-fold" @click="showTransferDialog(task)">转办</el-button>
</div>
<div>
<p><strong>流程名称:</strong> {{ task.流程标题 }}</p>
<p><strong>申请人:</strong> {{ task.申请人 }}</p>
<p><strong>申请时间:</strong> {{ task.申请时间 }}</p>
<p><strong>当前节点:</strong> {{ task.当前节点 }}</p>
<p><strong>描述:</strong> {{ task.流程描述 }}</p>
<p><strong>已关联生产订单:</strong> {{ task.已关联计划号 }}</p>
<p><strong>物料名称:</strong> {{ task.零件名称 }}</p>
<p><strong>物料编号:</strong> {{ task.零件编号 }}</p>
<p><strong>工序名称:</strong> {{ task.工序名称 }}</p>
</div>
</el-card>
</div>
<div v-else class="empty-state">
<el-empty description="暂无待处理任务"></el-empty>
</div>
</el-tab-pane>
<!-- 我发起的 -->
<el-tab-pane label="我发起的" name="initiated">
<div class="filter-bar">
<el-input placeholder="搜索流程名称" v-model="filters.initiated.keyword" class="filter-item" style="width: 200px;" clearable>
<el-button slot="append" icon="el-icon-search"></el-button>
</el-input>
<el-select v-model="filters.initiated.status" placeholder="状态" class="filter-item" clearable>
<el-option label="审批中" value="processing"></el-option>
<el-option label="已完成" value="completed"></el-option>
<el-option label="已拒绝" value="rejected"></el-option>
</el-select>
<el-button type="primary" icon="el-icon-plus" @click="showCreateDialog" style="width: auto;">发起新流程</el-button>
</div>
<el-table :data="filteredInitiatedProcesses" style="width: 100%">
<el-table-column prop="流程标题" label="流程名称" width="150"></el-table-column>
<el-table-column prop="发起时间" label="发起时间" width="200"></el-table-column>
<el-table-column prop="当前节点" label="当前节点" width="120"></el-table-column>
<el-table-column prop="状态" label="状态" width="100">
<template slot-scope="scope">
<el-tag :type="getStatusType(scope.row.状态)">
{{ getStatusText(scope.row.状态) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<el-button type="text" @click="viewProcessDetail(scope.row)">查看进度</el-button>
<el-button v-if="scope.row.状态 === 'processing'" type="text" @click="showCompleteDialog(scope.row)">完结</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<!-- 我已处理 -->
<el-tab-pane label="我已处理" name="processed">
<el-table :data="processedTasks" style="width: 100%">
<el-table-column prop="流程名称" label="流程名称" width="150"></el-table-column>
<el-table-column prop="申请人" label="申请人" width="100"></el-table-column>
<el-table-column prop="处理时间" label="处理时间" width="200"></el-table-column>
<el-table-column prop="处理结果" label="处理结果" width="100">
<template slot-scope="scope">
<el-tag v-if="scope.row.处理结果 === 'transferred'">
转办
</el-tag>
<el-tag v-else :type="scope.row.处理结果 === 'approved' ? 'success' : 'danger'">
{{ scope.row.处理结果 === 'approved' ? '同意' : '拒绝' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="审批意见" label="审批意见"></el-table-column>
<el-table-column label="操作" width="100">
<template slot-scope="scope">
<el-button type="text" @click="viewProcessDetail(scope.row)">查看详情</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
<!-- 发起流程对话框 -->
<el-dialog title="发起新流程" :visible.sync="createDialogVisible" width="1000px" :close-on-click-modal="false" :append-to-body="true">
<el-form :model="newProcessForm" label-width="120px" :rules="formRules" ref="processForm">
<!-- 基础信息 -->
<div class="form-section">
<div class="form-section-title">
<i class="el-icon-info"></i>基础信息
</div>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="优先级" prop="priority">
<el-select v-model="newProcessForm.priority" placeholder="请选择优先级" style="width: 100%">
<el-option label="普通" value="normal"></el-option>
<el-option label="高" value="high"></el-option>
<el-option label="紧急" value="urgent"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="流程标题" prop="title">
<el-input v-model="newProcessForm.title" placeholder="请输入流程标题"></el-input>
</el-form-item>
<el-form-item label="流程描述" prop="description">
<el-input type="textarea" v-model="newProcessForm.description" :rows="3"
placeholder="请输入流程详细描述"></el-input>
</el-form-item>
<!-- 审批流程设置 -->
<div class="form-section" v-if="newProcessForm.type">
<div class="form-section-title">
<i class="el-icon-s-check"></i>审批流程设置
</div>
<el-form-item label="审批人" prop="approverIds">
<el-select
v-model="newProcessForm.approverIds"
multiple
filterable
clearable
collapse-tags
placeholder="请选择审批人"
style="width: 100%;">
<el-option
v-for="user in userList"
:key="user.id"
:label="user.name"
:value="user.id">
</el-option>
</el-select>
</el-form-item>
</div>
</div>
<div class="form-section">
<div class="form-section-title">
<i class="el-icon-info"></i>绑定任务信息
</div>
<el-form-item v-if="selectedRow" label="已关联生产订单">
<el-input v-model="tableOrderNum" placeholder="" readonly></el-input>
</el-form-item>
<el-form-item v-if="selectedRow" label="物料名称">
<el-input v-model="tableProductName" placeholder="" readonly></el-input>
</el-form-item>
<el-form-item v-if="selectedRow" label="物料编号">
<el-input v-model="tableProductCode" placeholder="" readonly></el-input>
</el-form-item>
<el-form-item v-if="selectedRow" label="工序名称">
<el-input v-model="tableProcessName" placeholder="" readonly></el-input>
</el-form-item>
<div class="search-container">
<span class="show-text">生产订单:</span>
<el-input v-model="orderNo" placeholder="请输入生产订单" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">产品编码:</span>
<el-input v-model="productCode" placeholder="请输入产品编码" clearable style="width: 150px;margin-right: 10px" />
<span class="show-text">产品名称:</span>
<el-input v-model="productName" placeholder="请输入产品名称" clearable style="width: 150px;margin-right: 10px" />
<el-button :disabled="loading" icon="el-icon-search" plain type="primary" @click="searchTable3()">查询</el-button>
</div>
<div class="custom-tabs">
<el-table v-loading="loading" :data="tableData5" :height="'40vh'" border
element-loading-background="rgba(0, 0, 0, 0.2)" element-loading-spinner="el-icon-loading"
highlight-current-row size="mini" style="width: 100%;" tooltip-effect="dark"
@row-click="handleRowClick">
<el-table-column align="center" label="序号" type="index" width="50" fixed />
<el-table-column align="center" prop="合同号" label="销售订单" width="120" fixed />
<el-table-column align="center" prop="订单号" label="生产订单" width="100" fixed />
<el-table-column align="center" prop="产品编码" label="零件编码" width="220" />
<el-table-column align="center" prop="产品名称" label="产品名称" width="190" />
<el-table-column align="center" prop="计划数量" label="计划数" width="80" />
<el-table-column align="center" prop="工序名称" label="工序名称" width="120" />
<el-table-column align="center" prop="指派对象编号" label="指派对象编号" width="120" />
<el-table-column align="center" prop="指派对象" label="指派对象" width="120" />
<el-table-column align="center" prop="指派数量" label="指派数量" width="120" />
<el-table-column align="center" prop="计划开始时间" label="计划开始时间" width="120" />
<el-table-column align="center" prop="计划完成时间" label="计划完成时间" width="120" />
<el-table-column align="center" prop="最晚开始时间" label="最晚开始时间" width="120" />
<el-table-column align="center" label="要求完工日期" width="120">
<template slot-scope="scope">
{{ formatDate(scope.row.要求完工日期) }}
</template>
</el-table-column>
</el-table>
</div>
</div>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="createDialogVisible = false"> </el-button>
<el-button type="primary" @click="submitNewProcess"> </el-button>
</span>
</el-dialog>
<!-- 处理任务对话框 -->
<el-dialog title="处理任务" :visible.sync="handleDialogVisible" width="700px" :append-to-body="true">
<div v-if="currentTask">
<el-descriptions :column="2" border>
<el-descriptions-item label="申请人">{{ currentTask.申请人 }}</el-descriptions-item>
<el-descriptions-item label="申请时间">{{ currentTask.申请时间 }}</el-descriptions-item>
<el-descriptions-item label="优先级">
<el-tag :type="getPriorityType(currentTask.优先级)">
{{ getPriorityText(currentTask.优先级) }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="描述" :span="2">{{ currentTask.流程描述 }}</el-descriptions-item>
<el-descriptions-item label="已关联生产订单">{{ currentTask.已关联计划号 }}</el-descriptions-item>
<el-descriptions-item label="物料名称">{{ currentTask.零件名称 }}</el-descriptions-item>
<el-descriptions-item label="物料编号">{{ currentTask.零件编号 }}</el-descriptions-item>
<el-descriptions-item label="工序名称">{{ currentTask.工序名称 }}</el-descriptions-item>
</el-descriptions>
<el-divider></el-divider>
<el-form :model="handleForm" label-width="100px" ref="approvalForm">
<el-form-item label="处理意见" required>
<el-radio-group v-model="handleForm.result">
<el-radio label="approved">同意</el-radio>
<el-radio label="rejected">拒绝</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="审批意见">
<el-input type="textarea" v-model="handleForm.comment" :rows="3" placeholder="请输入审批意见"></el-input>
</el-form-item>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="handleDialogVisible = false"> </el-button>
<el-button type="primary" @click="submitHandle(currentTask)"> </el-button>
</span>
</el-dialog>
<!-- 查看流程进度对话框 -->
<el-dialog title="流程进度详情" :visible.sync="detailDialogVisible" width="800px" :append-to-body="true">
<div v-if="currentProcess">
<el-descriptions :column="2" border>
<el-descriptions-item label="流程名称">{{ currentProcess.processInfo.流程标题 }}</el-descriptions-item>
<el-descriptions-item label="发起人">{{ currentProcess.processInfo.发起人姓名 }}</el-descriptions-item>
<el-descriptions-item label="发起时间">{{ currentProcess.processInfo.创建时间 }}</el-descriptions-item>
<el-descriptions-item label="当前状态">
<el-tag :type="getStatusType(currentProcess.processInfo.状态)">
{{ getStatusText(currentProcess.processInfo.状态) }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="已关联生产订单">{{ currentProcess.processInfo.已关联计划号 }}</el-descriptions-item>
<el-descriptions-item label="物料名称">{{ currentProcess.processInfo.零件名称 }}</el-descriptions-item>
<el-descriptions-item label="物料编号">{{ currentProcess.processInfo.零件编号 }}</el-descriptions-item>
<el-descriptions-item label="工序名称">{{ currentProcess.processInfo.工序名称 }}</el-descriptions-item>
</el-descriptions>
<el-divider></el-divider>
<h4>审批流程</h4>
<el-steps :active="currentProcess.processInfo.当前步骤" align-center style="margin: 20px 0;">
<el-step v-for="(step, index) in currentProcess.steps" :key="index"
:title="step.标题" :description="step.描述"></el-step>
</el-steps>
<el-divider></el-divider>
<h4>审批记录</h4>
<el-timeline style="margin-top: 20px;">
<el-timeline-item v-if="record.处理结果 != 'transferred'" v-for="(record, index) in currentProcess.approvalRecords"
:key="index" :timestamp="record.时间" :type="record.处理结果 === 'approved' ? 'success' : 'danger'"
:icon="record.处理结果 === 'approved' ? 'el-icon-check' : 'el-icon-close'">
<el-card>
<h4>{{ record.审批人姓名 }} - {{ record.处理结果 === 'approved' ? '同意' : '拒绝' }}</h4>
<p>{{ record.审批意见 || '无备注' }}</p>
</el-card>
</el-timeline-item>
<el-timeline-item v-if="record.处理结果 == 'transferred'" v-for="(record, index) in currentProcess.approvalRecords"
:key="index" :timestamp="record.时间" :type="'success'"
:icon="'el-icon-check'">
<el-card>
<h4>{{ record.审批人姓名 }}-转办</h4>
<p>{{ record.审批意见 || '无备注' }}</p>
</el-card>
</el-timeline-item>
</el-timeline>
</div>
</el-dialog>
<!-- 转办对话框 -->
<el-dialog title="转办流程" :visible.sync="transferDialogVisible" width="700px" :append-to-body="true">
<el-form :model="transferForm" label-width="100px">
<el-form-item label="目标人员" required>
<el-select v-model="transferForm.newApproverId" placeholder="请选择人员" style="width: 100%">
<el-option v-for="user in users" :key="user.id"
:label="user.name" :value="user.id">
<span>{{ user.name }}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="转办原因" required>
<el-input type="textarea" v-model="transferForm.reason" :rows="3" placeholder="请输入转办原因"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="transferDialogVisible = false"> </el-button>
<el-button type="primary" @click="confirmTransfer" :loading="transferLoading"> </el-button>
</span>
</el-dialog>
<!-- 完结对话框 -->
<el-dialog title="完结流程" :visible.sync="completeDialogVisible" width="700px" class="complete-dialog" :append-to-body="true">
<el-form :model="completeForm" label-width="120px">
<el-form-item label="流程名称">
<div>{{ selectProcess ? selectProcess.流程标题 : '' }}</div>
</el-form-item>
<el-form-item label="完结原因" required>
<el-input type="textarea" v-model="completeForm.reason" :rows="3"
placeholder="请输入完结原因"></el-input>
</el-form-item>
<el-form-item label="完结结果" required>
<el-radio-group v-model="completeForm.result">
<el-radio label="completed">完成</el-radio>
<el-radio label="cancelled">取消</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="completeDialogVisible = false"> </el-button>
<el-button type="primary" @click="confirmComplete" :loading="completeLoading" style="width: auto;"> </el-button>
</span>
</el-dialog>
</div>
</div>
</template>
<script>
export default {
name: 'WorkflowManagement',
props: {
initialSelectedRow: {
type: Object,
default: null
}
},
data() {
return {
// 搜索条件
orderNo: '',
contractNo: '',
productCode: '',
productName: '',
processName: '',
nature: '',
completionTime: [],
productionStatus: '',
tableData5: [],
activeTab: 'pending',
tableOrderNum: '',
tableProductCode: '',
tableProductName: '',
tableProcessName: '',
selectedRow: '',
loading: false,
// 转办相关数据
transferDialogVisible: false,
transferLoading: false,
// 完结相关数据
completeDialogVisible: false,
completeLoading: false,
currentTask: null,
currentProcess: null,
selectProcess: null,
transferForm: {
newApproverId: '',
newApproverName: '',
reason: ''
},
completeForm: {
reason: '',
result: 'completed'
},
createDialogVisible: false,
handleDialogVisible: false,
detailDialogVisible: false,
submitting: false,
filters: {
pending: { keyword: '', priority: '', type: '' },
initiated: { keyword: '', status: '' }
},
newProcessForm: {
type: '',
priority: 'normal',
title: '',
description: '',
approverIds: []
},
formRules: {
title: [{ required: true, message: '请输入流程标题', trigger: 'blur' }],
description: [{ required: true, message: '请输入流程描述', trigger: 'blur' }],
approverIds: [{ type: 'array', required: true, message: '请选择审批人', trigger: 'change' }]
},
handleForm: {
result: 'approved',
comment: ''
},
userList: [],
stats: {
pending: 0,
initiated: 0,
completed: 0,
},
// 数据
pendingTasks: [],
initiatedProcesses: [],
processedTasks: [],
users: [],
};
},
computed: {
filteredPendingTasks() {
let tasks = this.pendingTasks;
if (this.filters.pending.keyword) {
tasks = tasks.filter(task =>
task.流程标题.includes(this.filters.pending.keyword)
);
}
if (this.filters.pending.priority) {
tasks = tasks.filter(task => task.优先级 == this.filters.pending.priority);
}
return tasks;
},
filteredInitiatedProcesses() {
let processes = this.initiatedProcesses;
if (this.filters.initiated.keyword) {
processes = processes.filter(process =>
process.流程标题.includes(this.filters.initiated.keyword)
);
}
if (this.filters.initiated.status) {
processes = processes.filter(process => process.状态 === this.filters.initiated.status);
}
return processes;
}
},
created() {
this.applyInitialSelectedRow();
this.searchTable();
this.searchTable1();
this.getUserList();
this.getProcessedTasks();
this.searchTable3();
},
watch: {
initialSelectedRow: {
handler() {
this.applyInitialSelectedRow();
},
deep: true
}
},
methods: {
// 数据查询方法
switchTab(tabName) {
this.activeTab = tabName
this.refreshActiveTab(tabName)
},
handleTabClick(tab) {
this.refreshActiveTab(tab.name)
},
refreshActiveTab(tabName = this.activeTab) {
if (tabName === 'pending') {
this.searchTable1()
} else if (tabName === 'initiated') {
this.searchTable()
} else if (tabName === 'processed') {
this.getProcessedTasks()
}
},
getProcessedTasks() {
var params = []
params.push(['审批人ID', this.$store.state.user.id])
const data = this.CreateData('11', 'sp_获取最近处理任务', params)
this.ExecDatabase(data).then((response) => {
this.processedTasks = response.data || []
this.stats.completed = this.processedTasks.length
})
},
getUserList() {
const data = this.CreateData('11', '人员管理_人员信息查询')
this.ExecDatabase(data).then((response) => {
response.data.forEach(item => {
this.users.push({ id: item.Personnel_Number, name: item.Personnel_Name })
this.userList.push({ id: item.Personnel_Number, name: item.Personnel_Name })
});
console.log( this.userList)
}).catch(() => {
this.$message.error('处理失败')
})
},
searchTable() {
var params = []
params.push(['发起人ID', this.$store.state.user.id])
params.push(['状态', null])
var data = this.CreateData('11', 'sp_获取我的流程', params)
this.ExecDatabase(data).then(response => {
this.loading = false
this.initiatedProcesses = response.data || [];
this.stats.initiated = this.initiatedProcesses.length
}).catch(() => {
this.loading = false
})
},
searchTable1() {
var params = []
params.push(['审批人ID', this.$store.state.user.id])
var data = this.CreateData('11', 'sp_获取待处理任务', params)
this.ExecDatabase(data).then(response => {
this.loading = false
this.pendingTasks = response.data || [];
this.stats.pending = this.pendingTasks.length
}).catch(() => {
this.loading = false
})
},
searchTable3() {
this.loading = true
var params = []
params.push(['订单号', this.orderNo || 0])
params.push(['物料类型', '自制件'])
params.push(['合同号', this.contractNo])
params.push(['产品编码', this.productCode])
params.push(['产品名称', this.productName])
params.push(['工序名称', this.processName])
params.push(['性质', this.nature])
params.push(['要求完工日期1', this.completionTime ? this.completionTime[0] : ''])
params.push(['要求完工日期2', this.completionTime ? this.completionTime[1] : ''])
params.push(['排产状态', this.productionStatus])
params.push(['工位',''])
var data = this.CreateData('11', 'MES_ProductAdmin_Query', params)
this.ExecDatabase(data).then(response => {
this.loading = false
this.tableData5 = response.data || []
}).catch(() => {
this.loading = false
})
},
// 对话框控制方法
showCreateDialog() {
this.createDialogVisible = true;
this.resetNewProcessForm();
this.applyInitialSelectedRow();
},
showTransferDialog(task) {
this.currentTask = task;
this.transferForm = {
newApproverId: '',
newApproverName: '',
reason: ''
};
this.transferDialogVisible = true;
},
showCompleteDialog(process) {
this.selectProcess = process;
this.completeForm = {
reason: '',
result: 'completed'
};
this.completeDialogVisible = true;
},
handleTask(task) {
this.currentTask = task;
this.handleForm = {
result: 'approved',
comment: ''
};
this.handleDialogVisible = true;
},
// 表单操作方法
resetNewProcessForm() {
this.newProcessForm = {
type: true,
priority: 'normal',
title: '',
description: '',
approverIds: []
};
},
getSelectedApprovers() {
const selectedIds = this.newProcessForm.approverIds || [];
const approvers = selectedIds.map(id => {
return this.userList.find(user => String(user.id) === String(id));
}).filter(Boolean);
return approvers.filter((user, index, arr) => {
return arr.findIndex(item => String(item.id) === String(user.id)) === index;
});
},
// 数据处理方法
applyInitialSelectedRow() {
if (!this.initialSelectedRow || Object.keys(this.initialSelectedRow).length === 0) return
this.handleRowClick(this.initialSelectedRow)
this.orderNo = this.tableOrderNum
this.productCode = this.tableProductCode
this.productName = this.tableProductName
this.processName = this.tableProcessName
},
handleRowClick(row) {
this.selectedRow = row
this.tableOrderNum = row.订单号 || row.计划号 || row.生产订单 || ''
this.tableProductCode = row.产品编码 || row.零件编码 || row.物料编码 || ''
this.tableProductName = row.产品名称 || row.零件名称 || row.物料名称 || ''
this.tableProcessName = row.工序名称 || ''
},
formatDate(date) {
if (!date) return ''
return date.split(' ').length > 1 ? date.split(' ')[0] : date
},
// 提交处理方法
// 调用简化版存储过程的方法
submitNewProcess() {
if(!this.selectedRow){
return this.$message.warning('请选择绑定信息');
}
this.$refs.processForm.validate((valid) => {
if (valid) {
this.submitting = true;
const approvers = this.getSelectedApprovers();
if (approvers.length === 0) {
this.submitting = false;
return this.$message.warning('请选择审批人');
}
const approverId = approvers.map(user => user.id).join(',');
const approverName = approvers.map(user => user.name).join(',');
const params = []
params.push(['流程标题', this.newProcessForm.title])
params.push(['流程描述', this.newProcessForm.description])
params.push(['优先级', this.newProcessForm.priority || 'normal'])
params.push(['发起人ID', this.$store.state.user.id])
params.push(['发起人姓名', this.$store.state.user.name])
params.push(['审批人ID', approverId])
params.push(['审批人姓名', approverName])
params.push(['新流程ID', '0'])
params.push(['已关联计划号', this.tableOrderNum || ''])
params.push(['零件名称', this.tableProductName || ''])
params.push(['零件编号', this.tableProductCode || ''])
params.push(['工序名称', this.tableProcessName || ''])
console.log('简化版参数:', params);
// 调用简化版存储过程
const data = this.CreateData('11', 'sp_创建流程_简化版', params)
this.ExecDatabase(data).then((response) => {
console.log('简化版返回:', response);
if(response.data && response.data.length > 0){
const result = response.data[0];
if(result.结果 == 1){
this.$message.success('流程创建成功流程ID: ' + result.新流程ID);
this.createDialogVisible = false;
this.resetNewProcessForm();
this.searchTable();
this.searchTable1();
} else {
this.$message.error('创建失败: ' + (result.消息 || '未知错误'));
}
}
this.submitting = false;
}).catch((error) => {
console.error('API调用错误:', error);
this.$message.error('保存失败');
this.submitting = false;
})
}
});
},
submitHandle(task) {
const params = []
params.push(['流程ID', task.流程ID])
params.push(['节点ID', task.节点ID])
params.push(['审批人ID', this.$store.state.user.id])
params.push(['审批人姓名', this.$store.state.user.name])
params.push(['处理结果', this.$refs.approvalForm.model.result])
params.push(['审批意见', this.$refs.approvalForm.model.comment])
params.push(['成功',''])
const data = this.CreateData('12', 'sp_处理审批', params)
this.ExecDatabase(data).then((response) => {
this.$message.success('处理完成');
this.handleDialogVisible = false;
this.searchTable1();
this.getProcessedTasks();
}).catch(() => {
this.$message.error('处理失败')
})
},
confirmTransfer() {
if (!this.transferForm.newApproverId) {
this.$message.warning('请选择目标人员');
return;
}
this.users.forEach(user => {
if(user.id == this.transferForm.newApproverId){
this.transferForm.newApproverName = user.name
}
});
if (!this.transferForm.reason) {
this.$message.warning('请输入转办原因');
return;
}
this.transferLoading = true;
const params = []
params.push(['流程ID', this.currentTask.流程ID])
params.push(['节点ID', this.currentTask.节点ID])
params.push(['原审批人ID', this.$store.state.user.id])
params.push(['原审批人姓名', this.$store.state.user.name])
params.push(['新审批人ID', this.transferForm.newApproverId])
params.push(['新审批人姓名', this.transferForm.newApproverName])
params.push(['转办原因', this.transferForm.reason])
params.push(['成功', ''])
const data = this.CreateData('12', 'sp_转办流程', params)
this.ExecDatabase(data).then((response) => {
this.$message.success('转办成功!');
this.transferDialogVisible = false;
this.searchTable1();
}).catch(() => {
this.$message.error('保存失败')
}).finally(() => {
this.transferLoading = false;
})
},
confirmComplete() {
if (!this.completeForm.reason) {
this.$message.warning('请输入完结原因');
return;
}
const params = []
params.push(['流程ID', this.selectProcess.流程ID])
params.push(['发起人ID', this.$store.state.user.id])
params.push(['发起人姓名', this.$store.state.user.name])
params.push(['完成类型', this.completeForm.result])
params.push(['完成原因', this.completeForm.reason])
params.push(['成功', ''])
const data = this.CreateData('11', 'sp_完成流程', params)
this.ExecDatabase(data).then((response) => {
this.$message.success('操作成功!');
this.completeDialogVisible = false;
this.searchTable();
}).catch(() => {
this.$message.error('保存失败')
}).finally(() => {
this.completeLoading = false;
})
},
// 查看详情方法
viewProcessDetail(process) {
var params = []
params.push(['流程ID', process.流程ID])
var data = this.CreateData('11', 'sp_获取流程详情', params)
this.ExecDatabase(data).then(response => {
this.加载中 = false
const result = JSON.parse(response.data[0]["JSON_F52E2B61-18A1-11d1-B105-00805F49916B"])
const processInfo = JSON.parse(result.流程信息);
const steps = JSON.parse(result.步骤信息);
var approvalRecords = ''
if(result.审批记录){
approvalRecords = JSON.parse(result.审批记录);
}
this.currentProcess = {
'processInfo': processInfo,
'steps': steps,
'approvalRecords': approvalRecords,
}
console.log(this.currentProcess)
this.detailDialogVisible = true;
}).catch(() => {
this.加载中 = false
})
},
// 工具方法
getPriorityType(priority) {
const map = { urgent: 'danger', high: 'warning', normal: 'success' };
return map[priority] || 'info';
},
getPriorityText(priority) {
const map = { urgent: '紧急', high: '高', normal: '普通' };
return map[priority] || '普通';
},
getStatusType(status) {
const map = { processing: 'warning', completed: 'success', rejected: 'danger', cancelled: 'info' };
return map[status] || 'info';
},
getStatusText(status) {
const map = { processing: '审批中', completed: '已完成', rejected: '已拒绝', cancelled: '已取消' };
return map[status] || status;
},
isUrgent(deadline) {
return new Date(deadline) - new Date() < 24 * 60 * 60 * 1000;
},
}
};
</script>
<style>
.workflow-container {
padding: 20px;
min-height: 100%;
}
.page-header {
background: #fff;
padding: 20px;
margin-bottom: 20px;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
display: flex;
justify-content: space-between;
align-items: center;
}
.workflow-tabs {
background: #fff;
border-radius: 4px;
overflow: hidden;
}
.filter-bar {
padding: 15px;
background: #fff;
margin-bottom: 15px;
border-radius: 4px;
display: flex;
flex-wrap: wrap;
align-items: center;
}
.filter-item {
margin-right: 15px;
margin-bottom: 10px;
}
.process-card {
margin-bottom: 15px;
cursor: pointer;
transition: all 0.3s;
}
.process-card:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.priority-tag {
margin-left: 10px;
}
.footer-buttons {
margin-top: 20px;
text-align: right;
}
.empty-state {
text-align: center;
padding: 40px 0;
color: #909399;
}
.stats-card {
text-align: center;
padding: 20px;
cursor: pointer;
transition: all 0.3s;
}
.stats-card:hover {
transform: translateY(-5px);
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
}
.stats-number {
font-size: 24px;
font-weight: bold;
color: #409EFF;
margin: 10px 0;
}
.stats-label {
color: #909399;
}
.transfer-actions {
margin: 10px 0;
padding: 10px;
background: #f5f7fa;
border-radius: 4px;
}
.complete-dialog .el-dialog__body {
max-height: 60vh;
overflow-y: auto;
}
.node-status {
display: inline-block;
padding: 2px 8px;
border-radius: 4px;
font-size: 12px;
margin-left: 10px;
}
.status-transferred {
background: #fdf6ec;
color: #e6a23c;
}
</style>

View File

@@ -0,0 +1,61 @@
# 01-项目功能内容
## 页面
- 页面路径:`src/views/DeviceManagement/DeviceInformation/index.vue`
- 菜单/模块:设备管理 / 设备信息维护
- 原始文档:`doc/修改设备信息维护.docx`
## 本轮功能范围
1. 设备信息维护列表新增字段展示:
- 设备名称:来自 Excel `名称`,数据库字段 `名称`
- 公司编码(财务)
- 生产用名:复用原 `设备名称`
- 规格/型号:复用原 `设备型号`
- 设备信息
- 使用部门
- 入账日期
- 单位
- 数量
- 状态
- 维修记录
- 维保记录
- 工位绑定
- 主要设备
- 设备标准开机工时(小时)
- 特种设备
- 证书有效期至
2. 设备新增/编辑弹窗新增对应维护字段。
3. 公司编码(财务):
- 新增时必填。
- 编辑时前端置灰不可修改。
- 后端编辑过程不更新公司编码,避免绕过前端改动。
4. 工位绑定:
- 使用多选下拉。
- 选项来源:`MES_登录_工位与名称_查询`,即工位管理数据。
- 数据库存储为逗号分隔的工位号。
5. 主要设备、特种设备:
- 下拉选项为“是/否”。
6. 证书有效期至:
- 日期选择。
- 已过期:表格行红色背景并置顶。
- 30 天内到期:表格行黄色背景并靠前。
- 其他数据正常排序在后。
## 数据库对象
- 表:`dbo.基础数据_设备工位点检表`
- 查询过程:`dbo.设备管理_设备信息_查询`
- 新增过程:`dbo.设备管理_设备信息_增加`
- 编辑过程:`dbo.设备管理_设备信息_编辑`
- 删除过程:`dbo.设备管理_设备信息_删除`,本轮未改。
- 增量脚本:`db_backups/update_device_information_maintenance_20260629.sql`
- 设备名称字段与 Excel 导入脚本:`db_backups/add_device_name_and_import_excel_20260629.sql`
- Excel 日期修正脚本:`db_backups/fix_device_excel_import_dates_20260629.sql`
- 新增过程提示文本修正脚本:`db_backups/fix_device_add_company_code_message_20260629.sql`

View File

@@ -0,0 +1,58 @@
# 02-项目程序开发详细步骤
## 1. 需求解析
1.`doc/修改设备信息维护.docx` 提取文字需求。
2. 确认目标页面为 `src/views/DeviceManagement/DeviceInformation/index.vue`
3. 确认工位数据来源为 `MES_登录_工位与名称_查询`,与系统工位管理保持一致。
## 2. 数据库开发
1. 连接目标库 `192.168.2.92 / YL_MESDB`
2. 查询 `dbo.基础数据_设备工位点检表`,确认原表仅有旧字段。
3. 新增增量脚本 `db_backups/update_device_information_maintenance_20260629.sql`
4. 脚本内容:
- 使用 `COL_LENGTH` 判断字段是否存在,保证可重复执行。
- 新增设备档案字段:公司编码、设备信息、使用部门、入账日期、单位、数量、状态、维修记录、维保记录、工位绑定、主要设备、设备标准开机工时、特种设备、证书有效期至。
- 更新 `设备管理_设备信息_查询`,返回新字段并按证书有效期预警排序。
- 更新 `设备管理_设备信息_增加`,写入新增字段,并校验公司编码不能为空。
- 更新 `设备管理_设备信息_编辑`,更新新增字段,但不更新公司编码。
5. 使用 `sqlcmd -f 65001` 执行脚本,避免中文脚本编码问题。
## 3. 前端开发
1. 重写设备信息维护页面表格列,字段名与数据库返回保持一致。
2. 扩展新增/编辑表单字段。
3. 新增 `stationOptions`,通过 `MES_登录_工位与名称_查询` 加载工位管理数据。
4. 工位绑定使用 `el-select multiple collapse-tags`
5. 新增 `emptyForm`,统一新增和重置表单默认值。
6. 新增 `buildSubmitParams`,统一组装新增/编辑参数。
7. 新增 `getCertificateLevel``tableRowClassName``sortedTableData`
- 过期为 0置顶并红色。
- 30 天内为 1靠前并黄色。
- 其他为 2。
8. 表格使用横向宽度自动撑开,并固定操作列,适配新增多列。
## 4. 验证
1. 数据库字段验证:查询 `sys.columns`
2. 存储过程参数验证:查询 `sys.parameters`
3. 查询过程验证:执行 `EXEC dbo.[设备管理_设备信息_查询]`
4. 前端构建验证:执行 `npm run build`
5. 工作文档归档:复制原始 docx 到 `work/DeviceManagement/DeviceInformation` 并补齐 README 与 01-06 文档。
## 5. 设备信息 Excel 导入
1. 读取 `doc/设备信息.xlsx`,确认 Sheet1 共 89 行数据。
2. 新增数据库字段 `名称`,用于保存 Excel `名称` 列;原字段 `设备名称` 继续保存 Excel `生产用名`
3. 更新设备信息维护页面:
- 列表新增“设备名称”列,对应数据库字段 `名称`
- 新增/编辑弹窗新增“设备名称”输入框。
- 提交参数增加 `名称`
4. 新增脚本 `db_backups/add_device_name_and_import_excel_20260629.sql`
- `COL_LENGTH` 判断并新增 `名称` 字段。
- 更新新增/编辑存储过程参数和写入逻辑。
- 使用 `MERGE``公司编码` 导入或更新 89 行 Excel 数据,避免重复导入。
5. 首次导入后发现 Excel 日期对象受时区影响,部分入账日期早一天;新增 `db_backups/fix_device_excel_import_dates_20260629.sql`,按 Excel 单元格显示值修正入账日期。
6. 新增 `db_backups/fix_device_add_company_code_message_20260629.sql`,只重新发布新增过程,修正“公司编码不能为空”提示文本,避免重新执行整份导入脚本覆盖已修正日期。
7. 使用 `sqlcmd -f 65001` 执行数据库脚本,验证总数、样例数据和存储过程文本。

View File

@@ -0,0 +1,185 @@
# 03-推进台账
## 2026-06-29 第 1 轮:设备信息维护页面和数据库扩展
### 做了什么
- 解析 `doc/修改设备信息维护.docx`
- 确认目标页面 `src/views/DeviceManagement/DeviceInformation/index.vue`
- 确认工位绑定选项来源为 `MES_登录_工位与名称_查询`
- 连接目标数据库并确认旧表结构缺少需求字段。
- 新增数据库增量脚本并同步到 `YL_MESDB`
- 修改设备信息维护前端页面。
- 创建 `work/DeviceManagement/DeviceInformation` 工作目录并复制需求文档。
- 新增 README、功能内容、开发步骤、推进台账、任务矩阵、验收证据、决策记录。
### 改了哪些文件
- `src/views/DeviceManagement/DeviceInformation/index.vue`
- `db_backups/update_device_information_maintenance_20260629.sql`
- `work/DeviceManagement/DeviceInformation/修改设备信息维护.docx`
- `work/DeviceManagement/DeviceInformation/README.md`
- `work/DeviceManagement/DeviceInformation/01-项目功能内容.md`
- `work/DeviceManagement/DeviceInformation/02-项目程序开发详细步骤.md`
- `work/DeviceManagement/DeviceInformation/03-推进台账.md`
- `work/DeviceManagement/DeviceInformation/04-任务矩阵.md`
- `work/DeviceManagement/DeviceInformation/05-验收证据.md`
- `work/DeviceManagement/DeviceInformation/06-决策记录.md`
- `gptlog-process/gpdlog.md`
### 验证了什么
- `sqlcmd` 连接目标库成功。
- 新增字段已存在于 `dbo.基础数据_设备工位点检表`
- `设备管理_设备信息_查询/增加/编辑` 参数已更新。
- 查询过程可执行。
- `npm run build` 通过,仅有既有体积和 Browserslist 过期警告。
### 下一步
- 进入真实系统页面做新增、编辑、证书有效期颜色排序的人工验收。
- 如果现场要求“公司编码”历史数据也必填,需要补历史数据清洗或唯一性规则。
## 2026-06-29 第 2 轮:取消设备类型必填
### 做了什么
- 根据用户反馈,去掉设备信息维护新增/编辑表单中“设备类型”的必填校验。
### 改了哪些文件
- `src/views/DeviceManagement/DeviceInformation/index.vue`
- `work/DeviceManagement/DeviceInformation/03-推进台账.md`
- `work/DeviceManagement/DeviceInformation/04-任务矩阵.md`
- `gptlog-process/gpdlog.md`
### 验证了什么
- 代码层确认 `rules` 中已移除 `设备类型` 必填规则。
### 下一步
- 如需严格验证,可再次执行 `npm run build` 或进入页面直接新增无设备类型的设备记录。
## 2026-06-29 第 3 轮:修复入账日期和证书有效期编辑报错
### 做了什么
- 修复设备编辑时 `入账日期``证书有效期至` 无法修改的问题。
- 前端提交日期时改为传 `yyyy-MM-dd` 字符串或空字符串。
- 数据库新增修复脚本,将新增/编辑过程的两个日期入参改为 `nvarchar(50)`,在过程内使用 `TRY_CONVERT(date, NULLIF(..., ''))` 转换。
### 改了哪些文件
- `src/views/DeviceManagement/DeviceInformation/index.vue`
- `db_backups/fix_device_information_date_edit_20260629.sql`
- `work/DeviceManagement/DeviceInformation/03-推进台账.md`
- `work/DeviceManagement/DeviceInformation/04-任务矩阵.md`
- `work/DeviceManagement/DeviceInformation/05-验收证据.md`
- `gptlog-process/gpdlog.md`
### 验证了什么
- 执行修复 SQL 到 `192.168.2.92 / YL_MESDB` 成功。
- 验证 `设备管理_设备信息_增加/编辑``@入账日期``@证书有效期至` 参数已变更为 `nvarchar`
- 直接执行 `设备管理_设备信息_编辑`,传入正常日期 `2026-07-01``2026-07-31`,返回 `result=1` 且数据库日期更新成功。
- 直接执行 `设备管理_设备信息_编辑`,传入空字符串日期,返回 `result=1` 且数据库日期保存为 `NULL`
### 下一步
- 到真实页面再执行一次编辑日期和清空日期的人工验收。
## 2026-06-29 第 4 轮:修复日期控件点击报错
### 做了什么
- 针对页面点击日期时报 `date.getHours is not a function` 的问题,修正前端日期控件绑定方式。
- 去掉 `el-date-picker``value-format="yyyy-MM-dd"`,让 Element UI 日期控件内部绑定 `Date` 对象。
- 编辑回填时使用 `parseDateValue` 将数据库日期转换为本地 `Date` 对象。
- 提交时继续通过 `dateParam` 格式化为 `yyyy-MM-dd` 字符串,兼容已修复的数据库过程。
### 改了哪些文件
- `src/views/DeviceManagement/DeviceInformation/index.vue`
- `work/DeviceManagement/DeviceInformation/03-推进台账.md`
- `work/DeviceManagement/DeviceInformation/04-任务矩阵.md`
- `work/DeviceManagement/DeviceInformation/05-验收证据.md`
- `gptlog-process/gpdlog.md`
### 验证了什么
- 代码层确认两个 `el-date-picker` 已移除 `value-format`
- 代码层确认编辑回填日期使用 `parseDateValue` 返回 `Date` 对象。
- 执行 `npm run build` 通过,仅有既有资源体积和 Browserslist 过期警告。
### 下一步
- 在真实页面点击日期面板并选择新日期,确认不再出现 `date.getHours is not a function`
## 2026-06-29 第 5 轮:修复编辑弹窗日期不回填
### 做了什么
- 确认数据库和列表数据有值;同时恢复测试记录 `设备流水号=1` 的日期为 `2026-07-01``2026-07-31`
- 增强 `formatDate``parseDateValue`,兼容 `yyyy-MM-dd``yyyy-MM-dd HH:mm:ss``yyyy/MM/dd``/Date(...)``Date` 对象等返回格式。
- 将新增表单日期默认值从空字符串改为 `null`,符合 Element UI 日期控件空值约定。
- 编辑回填时不再整体替换 `form` 对象,改为逐字段 `$set`,并在 `$nextTick` 后再次设置两个日期字段,避免被 `resetFields` 或弹窗初始化覆盖。
### 改了哪些文件
- `src/views/DeviceManagement/DeviceInformation/index.vue`
- `work/DeviceManagement/DeviceInformation/03-推进台账.md`
- `work/DeviceManagement/DeviceInformation/04-任务矩阵.md`
- `work/DeviceManagement/DeviceInformation/05-验收证据.md`
- `gptlog-process/gpdlog.md`
### 验证了什么
- 数据库记录 `设备流水号=1``入账日期=2026-07-01``证书有效期至=2026-07-31`
- 本地 Node 脚本验证多种日期格式可解析为有效 `Date`
- 执行 `npm run build` 通过,仅有既有资源体积和 Browserslist 过期警告。
- 本地 dev server 监听 `https://127.0.0.1:1997/`,命令行访问因自签名证书被拦截,需浏览器允许证书后测试页面。
### 下一步
- 在浏览器打开 `https://127.0.0.1:1997/`,登录后进入设备信息维护页面,点击编辑验证两个日期是否回填。
## 2026-06-29 第 6 轮:新增设备名称字段并导入设备信息 Excel
### 做了什么
- 根据用户要求新增“设备名称”字段,页面列表和新增/编辑弹窗均增加该字段。
- 读取 `doc/设备信息.xlsx`,确认 Sheet1 共 89 行数据,并复制到 `work/DeviceManagement/DeviceInformation/设备信息.xlsx` 归档。
- 明确字段映射Excel `名称` 保存到新增数据库字段 `名称`Excel `生产用名` 继续保存到原字段 `设备名称`
- 新增并执行 Excel 导入脚本,按 `公司编码` 使用 `MERGE` 导入,防止重复执行造成重复数据。
- 发现 Excel 日期导入存在时区早一天问题后,新增日期修正脚本,按 Excel 显示日期修正 `入账日期`
- 修正新增存储过程里“公司编码不能为空”提示文本,避免脚本生成时遗留问号文本。
### 改了哪些文件
- `src/views/DeviceManagement/DeviceInformation/index.vue`
- `db_backups/add_device_name_and_import_excel_20260629.sql`
- `db_backups/fix_device_excel_import_dates_20260629.sql`
- `db_backups/fix_device_add_company_code_message_20260629.sql`
- `work/DeviceManagement/DeviceInformation/README.md`
- `work/DeviceManagement/DeviceInformation/01-项目功能内容.md`
- `work/DeviceManagement/DeviceInformation/02-项目程序开发详细步骤.md`
- `work/DeviceManagement/DeviceInformation/03-推进台账.md`
- `work/DeviceManagement/DeviceInformation/04-任务矩阵.md`
- `work/DeviceManagement/DeviceInformation/05-验收证据.md`
- `work/DeviceManagement/DeviceInformation/06-决策记录.md`
- `gptlog-process/gpdlog.md`
### 验证了什么
- 数据库表 `dbo.基础数据_设备工位点检表` 已新增 `名称` 字段。
- `doc/设备信息.xlsx` 89 行已导入数据库,导入后设备信息总数为 89。
- 样例数据验证:
- `REALLY-11`:设备名称 `气泵(空压机)`,生产用名 `气泵`,入账日期 `2007-01-01`
- `REALLY-6`:设备名称 `数控加工中心`,生产用名 `加1`,入账日期 `2008-12-24`
- `REALLY-1`:设备名称 `普通车床`,生产用名 `普1`,入账日期 `2011-01-01`
- 执行 `npm run build` 通过,仅有既有资源体积和 Browserslist 过期警告。
### 下一步
- 在浏览器打开 `https://127.0.0.1:1997/`,进入设备信息维护页面检查新增字段显示、编辑回填和保存。

View File

@@ -0,0 +1,25 @@
# 04-任务矩阵
| 任务编号 | 任务 | 状态 | 验收标准 |
| --- | --- | --- | --- |
| DI-001 | 解析需求文档 | 已完成 | 已从 `doc/修改设备信息维护.docx` 提取字段和交互要求 |
| DI-002 | 定位目标页面 | 已完成 | 确认页面为 `src/views/DeviceManagement/DeviceInformation/index.vue` |
| DI-003 | 扩展数据库字段 | 已完成 | `dbo.基础数据_设备工位点检表` 已包含 14 个新增字段 |
| DI-004 | 更新查询过程 | 已完成 | 查询过程返回新增字段,并按证书有效期预警排序 |
| DI-005 | 更新新增过程 | 已完成 | 新增过程接收新增字段,公司编码为空时返回失败 |
| DI-006 | 更新编辑过程 | 已完成 | 编辑过程更新新增字段但不更新公司编码 |
| DI-007 | 修改列表列展示 | 已完成 | 前端表格展示需求字段,操作列固定在右侧 |
| DI-008 | 修改新增/编辑表单 | 已完成 | 表单包含需求字段,主要设备/特种设备为是/否下拉 |
| DI-008A | 取消设备类型必填 | 已完成 | `rules` 中不再包含设备类型必填校验,新增/编辑允许设备类型为空 |
| DI-009 | 工位绑定多选 | 已完成 | 工位绑定为多选下拉,选项来源于工位管理查询 |
| DI-010 | 证书有效期预警 | 已完成 | 已过期红色置顶30 天内黄色靠前 |
| DI-011 | 构建验证 | 已完成 | `npm run build` 通过 |
| DI-011A | 修复日期编辑报错 | 已完成 | 入账日期、证书有效期至可传正常日期或空字符串,存储过程返回成功 |
| DI-011B | 修复日期控件点击报错 | 已完成 | 日期控件绑定 `Date` 对象,点击日期面板不再触发 `date.getHours is not a function` |
| DI-011C | 修复编辑弹窗日期不回填 | 已完成 | 日期回填兼容多种后端返回格式,并在弹窗渲染后再次写入日期字段 |
| DI-014 | 新增设备名称字段 | 已完成 | 数据库新增 `名称` 字段,页面列表和编辑弹窗显示“设备名称” |
| DI-015 | 导入设备信息 Excel | 已完成 | `doc/设备信息.xlsx` 89 行导入数据库,按公司编码 MERGE 防重复 |
| DI-016 | 修正 Excel 入账日期 | 已完成 | 采用 Excel 显示日期修正导入结果,避免时区早一天 |
| DI-017 | 修正新增过程提示文本 | 已完成 | 新增过程公司编码为空时返回“公司编码不能为空”,不再返回问号乱码 |
| DI-012 | 真实页面人工验收 | 待办 | 登录系统确认页面显示、新增、编辑、预警颜色和排序符合需求 |
| DI-013 | 历史数据治理 | 观察 | 如历史设备缺公司编码影响业务,再补清洗脚本和规则 |

View File

@@ -0,0 +1,288 @@
# 05-验收证据
## 文档解析
- 原始文档:`doc/修改设备信息维护.docx`
- 工作副本:`work/DeviceManagement/DeviceInformation/修改设备信息维护.docx`
- 提取结果:字段包括公司编码、生产用名、规格/型号、设备信息、使用部门、入账日期、单位、数量、状态、维修记录、维保记录、工位绑定、主要设备、设备标准开机工时、特种设备、证书有效期至。
## 数据库连接
命令:
```powershell
sqlcmd -S 192.168.2.92 -d YL_MESDB -U sa -P ****** -Q "SET NOCOUNT ON; SELECT TOP 1 name FROM sys.databases WHERE name=N'YL_MESDB';"
```
结果:
- 返回 `YL_MESDB`
## 字段验证
命令:
```powershell
sqlcmd -S 192.168.2.92 -d YL_MESDB -U sa -P ****** -f 65001 -Q "SET NOCOUNT ON; SELECT c.name, t.name AS type_name, c.max_length, c.is_nullable FROM sys.columns c JOIN sys.types t ON c.user_type_id=t.user_type_id WHERE c.object_id=OBJECT_ID(N'dbo.基础数据_设备工位点检表') AND c.name IN (N'公司编码',N'设备信息',N'使用部门',N'入账日期',N'单位',N'数量',N'状态',N'维修记录',N'维保记录',N'工位绑定',N'主要设备',N'设备标准开机工时',N'特种设备',N'证书有效期至') ORDER BY c.column_id;"
```
结果:
- 已返回 14 个新增字段。
- 日期字段为 `date`
- 数量、设备标准开机工时为 `decimal`
- 文本字段为 `nvarchar`
## 存储过程参数验证
命令:
```powershell
sqlcmd -S 192.168.2.92 -d YL_MESDB -U sa -P ****** -f 65001 -Q "SET NOCOUNT ON; SELECT p.name AS proc_name, pa.name AS param_name, TYPE_NAME(pa.user_type_id) AS type_name FROM sys.procedures p JOIN sys.parameters pa ON p.object_id=pa.object_id WHERE p.name IN (N'设备管理_设备信息_查询',N'设备管理_设备信息_增加',N'设备管理_设备信息_编辑') ORDER BY p.name, pa.parameter_id;"
```
结果:
- `设备管理_设备信息_增加` 已包含新增字段参数。
- `设备管理_设备信息_编辑` 已包含新增字段参数和 `@设备流水号`
- `设备管理_设备信息_查询` 参数保持兼容。
## 查询过程验证
命令:
```powershell
sqlcmd -S 192.168.2.92 -d YL_MESDB -U sa -P ****** -f 65001 -Q "SET NOCOUNT ON; EXEC dbo.[设备管理_设备信息_查询] @设备名称_check=0, @设备名称=N'', @设备类型_check=0, @设备类型=NULL;" -h -1 -W
```
结果:
- 命令执行成功。
- 当前无输出行或未显示样本数据,但过程无执行错误。
## 前端构建
命令:
```powershell
npm run build
```
结果:
- 构建通过。
- webpack compiled with 2 warnings。
- 警告为项目既有资源体积过大、Browserslist/caniuse-lite 数据过期。
## 产物证据
- 前端页面:`src/views/DeviceManagement/DeviceInformation/index.vue`
- 数据库脚本:`db_backups/update_device_information_maintenance_20260629.sql`
- 日期编辑修复脚本:`db_backups/fix_device_information_date_edit_20260629.sql`
- 工作目录:`work/DeviceManagement/DeviceInformation`
- 日志:`gptlog-process/gpdlog.md`
## 日期编辑修复验证
命令:
```powershell
sqlcmd -S 192.168.2.92 -d YL_MESDB -U sa -P ****** -f 65001 -i db_backups\fix_device_information_date_edit_20260629.sql
```
结果:
- 脚本执行成功。
- `设备管理_设备信息_增加/编辑``@入账日期``@证书有效期至` 已调整为 `nvarchar` 参数。
正常日期验证:
```powershell
EXEC dbo.[设备管理_设备信息_编辑]
@入账日期=N'2026-07-01',
@证书有效期至=N'2026-07-31',
...
```
结果:
- 返回 `result = 1`
- 数据库保存为 `2026-07-01``2026-07-31`
清空日期验证:
```powershell
EXEC dbo.[设备管理_设备信息_编辑]
@入账日期=N'',
@证书有效期至=N'',
...
```
结果:
- 返回 `result = 1`
- 数据库对应日期字段保存为 `NULL`
前端构建复验:
```powershell
npm run build
```
结果:
- 构建通过。
- webpack compiled with 2 warnings。
- 警告仍为项目既有资源体积过大、Browserslist/caniuse-lite 数据过期。
## 设备名称字段和 Excel 导入验收
Excel 数据来源:
- `doc/设备信息.xlsx`
- 工作副本:`work/DeviceManagement/DeviceInformation/设备信息.xlsx`
- Sheet1 数据行数89 行。
导入脚本:
```powershell
sqlcmd -S 192.168.2.92 -d YL_MESDB -U sa -P ****** -f 65001 -i db_backups\add_device_name_and_import_excel_20260629.sql
```
结果:
- `dbo.基础数据_设备工位点检表` 已新增字段 `名称`
- `设备管理_设备信息_增加` 已增加 `@名称` 参数并写入 `[名称]`
- `设备管理_设备信息_编辑` 已增加 `@名称` 参数并更新 `[名称]`
- Excel 89 行按 `公司编码` 导入或更新。
日期修正脚本:
```powershell
sqlcmd -S 192.168.2.92 -d YL_MESDB -U sa -P ****** -f 65001 -i db_backups\fix_device_excel_import_dates_20260629.sql
```
结果:
- 使用 Excel 单元格显示值修正 `入账日期`
- 修正后设备信息总数为 89。
提示文本修正脚本:
```powershell
sqlcmd -S 192.168.2.92 -d YL_MESDB -U sa -P ****** -f 65001 -i db_backups\fix_device_add_company_code_message_20260629.sql
```
结果:
- 新增过程公司编码为空时返回 `公司编码不能为空`
- 未重新执行导入脚本,避免覆盖已修正的入账日期。
数据库抽样验证:
```powershell
SELECT COUNT(*) AS cnt
FROM dbo.[基础数据_设备工位点检表];
SELECT TOP 10
[设备流水号],
[名称],
[公司编码],
[设备名称] AS [生产用名],
[设备型号],
[入账日期]
FROM dbo.[基础数据_设备工位点检表]
ORDER BY [设备流水号];
```
结果:
- 总数89。
- `REALLY-11``名称=气泵(空压机)``生产用名=气泵``入账日期=2007-01-01`
- `REALLY-6``名称=数控加工中心``生产用名=加1``入账日期=2008-12-24`
- `REALLY-1``名称=普通车床``生产用名=普1``入账日期=2011-01-01`
前端构建验证:
```powershell
npm run build
```
结果:
- 构建通过。
- webpack compiled with 2 warnings。
- 警告仍为项目既有资源体积过大、Browserslist/caniuse-lite 数据过期。
## 编辑弹窗日期不回填修复验证
数据库测试数据:
```powershell
UPDATE dbo.[基础数据_设备工位点检表]
SET [入账日期]='2026-07-01',
[证书有效期至]='2026-07-31'
WHERE [设备流水号]=1;
```
结果:
- `设备流水号=1``入账日期``2026-07-01`
- `设备流水号=1``证书有效期至``2026-07-31`
本地日期解析验证:
```powershell
node -e "<日期解析测试脚本>"
```
结果:
- `2026-07-01`
- `2026-07-01 00:00:00`
- `2026/07/01 00:00:00`
- `/Date(1782864000000)/`
- `Date` 对象
以上格式均可解析为有效 `Date`
构建验证:
```powershell
npm run build
```
结果:
- 构建通过。
- webpack compiled with 2 warnings。
- 警告仍为项目既有资源体积过大、Browserslist/caniuse-lite 数据过期。
页面测试地址:
- `https://127.0.0.1:1997/`
- 本地 dev server 使用自签名 HTTPS浏览器需要允许证书后进入页面测试。
## 日期控件点击报错修复验证
问题:
- 页面点击 `入账日期``证书有效期至` 日期面板时报错:`TypeError: date.getHours is not a function`
修复:
- 移除两个 `el-date-picker``value-format="yyyy-MM-dd"`
- 编辑回填时用 `parseDateValue` 将数据库日期转换为 `Date` 对象。
- 提交时用 `dateParam` 再格式化为 `yyyy-MM-dd` 字符串。
验证命令:
```powershell
npm run build
```
结果:
- 构建通过。
- webpack compiled with 2 warnings。
- 警告仍为项目既有资源体积过大、Browserslist/caniuse-lite 数据过期。

View File

@@ -0,0 +1,49 @@
# 06-决策记录
## DR-001 公司编码编辑只读并由后端保护
- 决策:新增时公司编码必填;编辑时前端禁用;编辑存储过程不更新公司编码。
- 原因:需求明确“公司编码为必填且不可被修改”。仅前端禁用不足以防止接口绕过。
- 影响:历史数据若公司编码为空,编辑时不会强制补齐;如后续要求历史数据也完整,需要专项清洗。
## DR-002 生产用名和规格/型号复用旧字段
- 决策:生产用名使用 `设备名称`,规格/型号使用 `设备型号`
- 原因:需求明确“复用设备名称”“复用设备型号”,保持与既有存储过程和其他页面兼容。
- 影响:其他依赖 `设备管理_设备信息_查询` 的页面仍能使用旧字段。
## DR-003 工位绑定存储为逗号分隔工位号
- 决策:前端多选展示工位名称,提交时保存工位号逗号字符串到 `工位绑定`
- 原因:当前系统通用参数传递和旧表结构以简单字段为主,本轮避免新建关系表扩大影响面。
- 影响:后续如需要按单工位统计或约束唯一性,应迁移为设备-工位绑定明细表。
## DR-004 证书有效期排序前后端都处理
- 决策:数据库查询过程增加预警排序;前端 `sortedTableData` 再按同样规则排序并控制行背景色。
- 原因:后端保证分页查询顺序,前端保证当前页显示稳定和颜色一致。
- 影响:分页总数据的全局置顶依赖数据库排序;前端只处理当前页。
## DR-005 SQL 脚本使用可重复执行字段判断
- 决策:新增字段使用 `COL_LENGTH` 判断存在后再 `ALTER TABLE ADD`
- 原因:避免脚本重复执行时报“列已存在”。
- 影响:字段类型若后续要调整,需另起变更脚本,不能靠本脚本自动修改类型。
## DR-006 Excel 名称与生产用名分开保存
- 决策Excel `名称` 保存到新增数据库字段 `名称`页面显示为“设备名称”Excel `生产用名` 继续保存到原字段 `设备名称`,页面显示为“生产用名”。
- 原因:原系统多处依赖 `设备名称` 字段作为生产用名/设备简称,直接改语义会影响其他页面。
- 影响:后续涉及“设备名称”时应先确认是新字段 `名称` 还是旧字段 `设备名称`
## DR-007 Excel 导入按公司编码 MERGE
- 决策:设备信息 Excel 导入按 `公司编码``MERGE`,匹配则更新,不匹配则新增。
- 原因:用户要求把 Excel 数据插入数据库,但导入脚本可能被重复执行;使用 `MERGE` 可以降低重复数据风险。
- 影响Excel 中公司编码不是全局唯一的行会被视为同一设备;后续如要支持一编码多设备,需要新增更稳定的唯一键规则。
## DR-008 Excel 日期按显示值修正
- 决策:首次导入发现日期早一天后,单独使用 Excel 单元格显示值生成修正脚本,不重新执行整份导入脚本。
- 原因Node 读取 Excel 日期对象时受时区影响,显示值更贴近业务人员在表格中看到的日期。
- 影响:后续导入 Excel 日期时,应优先使用单元格显示文本或显式本地日期解析。

View File

@@ -0,0 +1,18 @@
# 修改设备信息维护 README
## 索引
| 文件 | 用途 |
| --- | --- |
| `修改设备信息维护.docx` | 原始需求文档副本 |
| `设备信息.xlsx` | 设备信息初始化导入数据副本 |
| `01-项目功能内容.md` | 本轮设备信息维护页面功能范围 |
| `02-项目程序开发详细步骤.md` | 前端、数据库和验证开发步骤 |
| `03-推进台账.md` | 每轮做了什么、改了哪些文件、验证了什么、下一步是什么 |
| `04-任务矩阵.md` | 任务编号、状态、验收标准 |
| `05-验收证据.md` | 命令、数据库、页面、构建等验收证据 |
| `06-决策记录.md` | 关键实现决策与原因 |
## 后续推进方式
后续继续该任务时,优先查看 `04-任务矩阵.md` 中状态为“待办”或“观察”的任务,再按 `03-推进台账.md` 追加新轮次记录。涉及数据库变更时,先补充 `db_backups` 增量脚本,再同步更新 `05-验收证据.md`

View File

@@ -0,0 +1,34 @@
# 01-项目功能内容
## 页面
- 页面路径:`src/views/PlanManagement/TimelyKitTrackingResult/index.vue`
- 菜单标题:及时齐套跟踪结果
- 菜单模块:计划排产
- 原始文档:`doc/新增及时齐套跟踪结果.docx`
## 功能范围
1. 新增“及时齐套跟踪结果”页面。
2. 一级数据字段和过滤条件按“计划用表”页面对齐。
3. 主表展示销售订单、计划号、生产订单、产品编码、产品名称、计划数量、入库数量、要求完工日、要求发货日、预计齐套时间、齐套、拣配状态、发料状态、装配开工、送检数量、终检、工艺、缺件项。
4. 展开行展示文档要求的绿色二级数据:
- 物料编码:`SAP.SBO_YL.dbo.VIEW_Jijiankukc.ItemCode`
- 物料名称:`SAP.SBO_YL.dbo.VIEW_Jijiankukc.U_Name`
- 缺件数量:`SAP.SBO_YL.dbo.VIEW_Jijiankukc.未发货数量`
- 属性:`SAP.SBO_YL.dbo.VIEW_Jijiankukc.属性`,属性为空时显示为外购
- 生产订单号:机加件按 SAP 物料编码匹配 MES 生产计划;装配按 SAP 物料编码 + 销售订单匹配 MES 生产计划;外购取 SAP `在制采购`
- 进度:属性不为空时参考生产计划跟踪当前序;外购为空
- 工艺路线:属性不为空时参考生产计划跟踪工艺路线;外购拼接采购员、采购未清数量、到货草稿、质检状态
- 预计完成时间:属性不为空时取 MES 任务最大计划完成时间;外购取 SAP 采购预计交货时间
## 数据库对象
- 查询过程:`dbo.生产管理_及时齐套跟踪结果_查询`
- SAP 视图:`[SAP].[SBO_YL].[dbo].[VIEW_Jijiankukc]`
- MES 视图:`dbo.View_生产订单_MES`
- 质检记录:`dbo.YL_质量检验_质检记录`
- 菜单表:`dbo.登录基础数据_二级菜单`
- 增量脚本:
- `db_backups/create_timely_kit_tracking_result_20260629.sql`
- `db_backups/add_timely_kit_tracking_result_menu_20260629.sql`

View File

@@ -0,0 +1,45 @@
# 02-项目程序开发详细步骤
## 1. 需求解析
1. 解包并读取 `doc/新增及时齐套跟踪结果.docx`
2. 确认需求:新增页面“及时齐套跟踪结果”,一级字段和过滤条件按“计划用表”一致,重点新增绿色二级缺件跟踪数据。
3. 确认 SAP 数据源为四段名:`[SAP].[SBO_YL].[dbo].[VIEW_Jijiankukc]`
## 2. 数据库开发
1. 新增 `db_backups/create_timely_kit_tracking_result_20260629.sql`
2. 创建或更新存储过程 `dbo.生产管理_及时齐套跟踪结果_查询`
3. 查询过程输入参数沿用“计划用表”:
- 订单号、物料类型、合同号、产品编码、产品名称、工序名称、计划开始、计划完成、排产状态、指派对象、计划号、发货状态、齐套、检验状态、发料状态、自制件属性。
4. 使用 `[SAP].[SBO_YL].[dbo].[VIEW_Jijiankukc]` 读取缺件明细。
5. 使用 `View_生产订单_MES` 匹配 MES 计划、任务状态、工艺路线和预计完成时间。
6. 使用 `YL_质量检验_质检记录` 判断终检和外购到货草稿对应的来料检验状态。
7. 脚本补充 `SET ANSI_NULLS ON``SET QUOTED_IDENTIFIER ON`,避免 XML `.value()` 和索引视图相关 SET 选项错误。
## 3. 菜单开发
1. 新增 `db_backups/add_timely_kit_tracking_result_menu_20260629.sql`
2. 以“计划用表”菜单为权限来源,复制已有角色的菜单授权。
3. 新菜单:
- `path = TimelyKitTrackingResult/index`
- `componet = /PlanManagement/TimelyKitTrackingResult/index`
- `name = TimelyKitTrackingResult`
- `title = 及时齐套跟踪结果`
## 4. 前端开发
1. 新增页面 `src/views/PlanManagement/TimelyKitTrackingResult/index.vue`
2. 主表过滤区参考 `src/views/PlanManagement/PlanShell/index.vue`
3. 主表一级字段按计划用表展示。
4. 使用 `el-table-column type="expand"` 展示缺件二级明细。
5. 二级行使用浅绿色背景,贴合原文档“绿色部分二级数据”的表达。
6. 状态字段使用与既有页面一致的绿色/橙色标签样式。
## 5. 验证
1. 执行查询脚本到 `YL_MESDB`
2. 执行菜单脚本,确认菜单写入 `登录基础数据_二级菜单`
3. 直接执行 `dbo.生产管理_及时齐套跟踪结果_查询`,确认 SAP linked server 可访问并返回数据。
4. 执行 `npm run build`,确认前端构建通过。
5. 复制原始 docx 到 `work/PlanManagement/TimelyKitTrackingResult` 并补齐 README、01-06 文档。

View File

@@ -0,0 +1,105 @@
# 03-推进台账
## 2026-06-29 第 1 轮:新增及时齐套跟踪结果页面
### 做了什么
- 解析 `doc/新增及时齐套跟踪结果.docx`,确认页面名称、字段来源和数据口径。
- 查找现有“计划用表”和“生产计划跟踪”页面,复用过滤条件、一级字段和当前序/工艺路线表达。
- 确认 SAP 缺件视图为 `[SAP].[SBO_YL].[dbo].[VIEW_Jijiankukc]`,并读取字段列表。
- 新增查询过程 `dbo.生产管理_及时齐套跟踪结果_查询`
- 新增菜单脚本,把“及时齐套跟踪结果”挂到计划排产模块,并复制“计划用表”的角色授权。
- 新增 Vue 页面 `src/views/PlanManagement/TimelyKitTrackingResult/index.vue`
- 创建 `work/PlanManagement/TimelyKitTrackingResult`,复制原始需求文档并补齐 README、01-06 文档。
- 将完整执行过程追加到 `/gptlog-process/gpdlog.md`
### 改了哪些文件
- `src/views/PlanManagement/TimelyKitTrackingResult/index.vue`
- `db_backups/create_timely_kit_tracking_result_20260629.sql`
- `db_backups/add_timely_kit_tracking_result_menu_20260629.sql`
- `work/PlanManagement/TimelyKitTrackingResult/新增及时齐套跟踪结果.docx`
- `work/PlanManagement/TimelyKitTrackingResult/README.md`
- `work/PlanManagement/TimelyKitTrackingResult/01-项目功能内容.md`
- `work/PlanManagement/TimelyKitTrackingResult/02-项目程序开发详细步骤.md`
- `work/PlanManagement/TimelyKitTrackingResult/03-推进台账.md`
- `work/PlanManagement/TimelyKitTrackingResult/04-任务矩阵.md`
- `work/PlanManagement/TimelyKitTrackingResult/05-验收证据.md`
- `work/PlanManagement/TimelyKitTrackingResult/06-决策记录.md`
- `gptlog-process/gpdlog.md`
### 验证了什么
- SQL 查询过程脚本执行成功。
- 菜单脚本执行成功,生成 4 条角色菜单记录。
- 直接执行 `dbo.生产管理_及时齐套跟踪结果_查询` 可返回 SAP 缺件和 MES 计划组合数据。
- 执行 `npm run build` 通过,仅有项目既有资源体积和 Browserslist/caniuse-lite 过期警告。
### 下一步
- 登录系统,在计划排产模块打开“及时齐套跟踪结果”,确认菜单可见、页面可查、展开行字段符合业务预期。
## 2026-06-29 第 2 轮:修正工艺路线、重复明细和外购一级数据
### 做了什么
- 根据反馈修正二级工艺路线展示,增加日期行、工序行、合格行和颜色。
- 查询过程新增 `工艺路线明细` JSON返回每道工序的计划日期、工序名称、指派对象、进度、完成数量、收检合格数和加工状态。
- 前端将自制件二级“工艺路线/采购状态”列从纯文本改为三行彩色工艺路线;外购仍显示采购状态文本。
- SQL 增加两层去重:
- SAP 原始缺件按 `DocEntry + Project + ItemCode + 属性` 取一条。
- 最终结果按 `订单号 + 缺件生产订单号` 取一条,避免同一生产订单号重复出现在二级数据。
- 修正外购一级数据口径:属性为空时使用 `SAP.DocEntry` 作为订单编号去匹配计划用表/MES 计划数据,而不是使用 `在制采购`
### 改了哪些文件
- `src/views/PlanManagement/TimelyKitTrackingResult/index.vue`
- `db_backups/create_timely_kit_tracking_result_20260629.sql`
- `work/PlanManagement/TimelyKitTrackingResult/03-推进台账.md`
- `work/PlanManagement/TimelyKitTrackingResult/04-任务矩阵.md`
- `work/PlanManagement/TimelyKitTrackingResult/05-验收证据.md`
- `work/PlanManagement/TimelyKitTrackingResult/06-决策记录.md`
- `gptlog-process/gpdlog.md`
### 验证了什么
- 重新发布 `dbo.生产管理_及时齐套跟踪结果_查询` 成功。
- 查询 `@订单号=7134` 时,同一生产订单号二级明细只返回 1 条。
- 查询 `@订单号=7335` 时,外购件已按 `SAP.DocEntry=7335` 匹配出计划用表一级数据。
- 执行 `npm run build` 通过,仅有项目既有资源体积和 Browserslist/caniuse-lite 过期警告。
### 下一步
- 登录页面人工检查展开行的三行工艺路线显示效果,确认颜色和计划用表页面一致。
## 2026-06-29 第 3 轮:修正外购质检状态和主数据匹配
### 做了什么
- 根据反馈重新拆分一级主数据和二级缺件数据的匹配职责。
- 一级主数据只按 `SAP.DocEntry = View_生产订单_MES.订单编号` 读取计划用表主订单,不再允许 SAP 缺件数据兜底生成主数据。
- 自制缺件单独通过缺件物料编码和合同号匹配二级生产订单,用于工艺路线、进度和缺件生产订单号。
- 外购缺件不再把主生产订单号作为缺件生产订单号;有到货草稿时显示到货草稿对应的采购入库检生产订单。
- 外购质检状态改为按采购入库检页面口径读取:根据 `SAP.到货草稿` 匹配 `质量检验_质检任务_SAP.订单编号`,再用入库数量和来料检验记录判断未完成/已完成。
- 非外购缺件的质检状态保持为空,避免误显示采购入库检状态。
### 改了哪些文件
- `db_backups/create_timely_kit_tracking_result_20260629.sql`
- `work/PlanManagement/TimelyKitTrackingResult/03-推进台账.md`
- `work/PlanManagement/TimelyKitTrackingResult/04-任务矩阵.md`
- `work/PlanManagement/TimelyKitTrackingResult/05-验收证据.md`
- `work/PlanManagement/TimelyKitTrackingResult/06-决策记录.md`
- `gptlog-process/gpdlog.md`
### 验证了什么
- 重新发布 `dbo.生产管理_及时齐套跟踪结果_查询` 成功。
- 查询 `@订单号=2007`,一级主数据字段完整,外购缺件生产订单号不再显示为主订单号 `2007`
- 查询 `@订单号=7321`,外购缺件根据 `到货草稿=11209` 显示二级生产订单号 `11209`,质检状态为采购入库检口径的未完成。
- 默认查询统计:总行数 198产品编码/产品名称为空行数 0缺件生产订单号等于主订单号行数 0非外购质检状态非空行数 0。
- 执行 `npm run build` 通过,仅有项目既有资源体积和 Browserslist/caniuse-lite 过期警告。
### 下一步
- 在页面刷新后检查前 1-10 行和第 32 行 `2007`,确认主数据、二级缺件、外购采购状态展示符合业务预期。

View File

@@ -0,0 +1,20 @@
# 04-任务矩阵
| 任务编号 | 任务 | 状态 | 验收标准 |
| --- | --- | --- | --- |
| TKR-001 | 解析需求文档 | 已完成 | 已从 `doc/新增及时齐套跟踪结果.docx` 提取字段和数据来源 |
| TKR-002 | 定位参考页面 | 已完成 | 确认一级字段和过滤条件参考 `PlanShell/index.vue` |
| TKR-003 | 确认 SAP 数据源 | 已完成 | `[SAP].[SBO_YL].[dbo].[VIEW_Jijiankukc]` 可查询并返回字段 |
| TKR-004 | 新增查询过程 | 已完成 | `dbo.生产管理_及时齐套跟踪结果_查询` 已创建并可返回数据 |
| TKR-005 | 新增菜单 | 已完成 | `登录基础数据_二级菜单` 已新增“及时齐套跟踪结果”菜单 |
| TKR-006 | 新增前端页面 | 已完成 | 页面文件已新增,主表和展开明细可渲染 |
| TKR-007 | 构建验证 | 已完成 | `npm run build` 通过 |
| TKR-008 | 工作文档归档 | 已完成 | README、01-06 文档和总日志已补齐 |
| TKR-011 | 工艺路线三行展示 | 已完成 | 二级工艺路线包含日期行、工序行、合格行,并按状态着色 |
| TKR-012 | 二级重复数据去重 | 已完成 | 同一一级数据下相同生产订单号只保留一条二级明细 |
| TKR-013 | 外购一级数据修正 | 已完成 | 属性为空时按 `SAP.DocEntry` 匹配计划用表一级数据 |
| TKR-014 | 一级主数据禁止 SAP 兜底 | 已完成 | 默认查询中产品编码/产品名称为空行数为 0不出现只有 SAP 缺件字段的假主数据 |
| TKR-015 | 外购二级生产订单号修正 | 已完成 | 外购缺件不再显示主生产订单号,有到货草稿时显示采购入库检生产订单 |
| TKR-016 | 外购质检状态按采购入库检口径 | 已完成 | 外购按 `到货草稿 -> 质量检验_质检任务_SAP -> YL_质量检验_质检记录` 判断未完成/已完成 |
| TKR-009 | 页面人工验收 | 待办 | 登录系统确认菜单可见、查询成功、展开行字段与业务一致 |
| TKR-010 | 采购质检匹配口径复核 | 观察 | 如业务确认到货草稿不是 `YL_质量检验_质检记录.计划号`,需调整质检状态匹配规则 |

View File

@@ -0,0 +1,200 @@
# 05-验收证据
## 文档解析
来源:
- `doc/新增及时齐套跟踪结果.docx`
解析结果:
- 页面名称:及时齐套跟踪结果。
- 一级数据字段根据计划用表页面一致。
- 过滤条件和计划用表页面一致。
- 二级数据来源:`SAP.SBO_YL.dbo.VIEW_Jijiankukc`
## SAP 视图验证
命令:
```powershell
sqlcmd -S 192.168.2.92 -d YL_MESDB -U sa -P ****** -f 65001 -Q "SELECT TOP 3 * FROM [SAP].[SBO_YL].[dbo].[VIEW_Jijiankukc];"
```
结果:
- SAP linked server 可访问。
- 返回字段包括 `ItemCode``U_Name``属性``未发货数量``在制采购``采购员``采购预计交货日期``采购未清数量``到货草稿`
## 查询过程验证
命令:
```powershell
sqlcmd -S 192.168.2.92 -d YL_MESDB -U sa -P ****** -f 65001 -i db_backups\create_timely_kit_tracking_result_20260629.sql
```
结果:
- 脚本执行成功。
- 初次取样时因 `QUOTED_IDENTIFIER` SET 选项不足报错,已在脚本中补充 `SET ANSI_NULLS ON``SET QUOTED_IDENTIFIER ON` 后重新发布。
取样命令:
```powershell
EXEC dbo.[生产管理_及时齐套跟踪结果_查询]
@订单号=0,
@物料类型=N'自制件',
@合同号=N'',
@产品编码=N'',
@产品名称=N'',
@工序名称=N'',
@计划开始=N'',
@计划完成=N'',
@排产状态=N'全部',
@指派对象=N'全部',
@计划号=N'',
@发货状态=N'全部',
@齐套=N'全部',
@检验状态=N'',
@发料状态=N'全部',
@自制件属性=N'全部';
```
结果:
- 查询可返回数据。
- 样例包含生产订单、产品编码、缺件物料编码、缺件数量、缺件属性、进度、工艺路线、预计完成时间、质检状态等字段。
## 菜单验证
命令:
```powershell
sqlcmd -S 192.168.2.92 -d YL_MESDB -U sa -P ****** -f 65001 -i db_backups\add_timely_kit_tracking_result_menu_20260629.sql
```
结果:
- 新增 4 条“及时齐套跟踪结果”菜单记录。
- 菜单路径:`TimelyKitTrackingResult/index`
- 组件路径:`/PlanManagement/TimelyKitTrackingResult/index`
## 前端构建验证
命令:
```powershell
npm run build
```
结果:
- 构建通过。
- webpack compiled with 2 warnings。
- 警告为项目既有资源体积过大和 Browserslist/caniuse-lite 数据过期。
## 产物证据
- 页面:`src/views/PlanManagement/TimelyKitTrackingResult/index.vue`
- 查询脚本:`db_backups/create_timely_kit_tracking_result_20260629.sql`
- 菜单脚本:`db_backups/add_timely_kit_tracking_result_menu_20260629.sql`
- 工作目录:`work/PlanManagement/TimelyKitTrackingResult`
- 总日志:`gptlog-process/gpdlog.md`
## 第 2 轮修正验证
重新发布查询过程:
```powershell
sqlcmd -S 192.168.2.92 -d YL_MESDB -U sa -P ****** -f 65001 -i db_backups\create_timely_kit_tracking_result_20260629.sql
```
结果:
- 执行成功。
- 查询过程新增最终去重层,按 `订单号 + 缺件生产订单号` 保留一条二级明细。
- 查询过程新增 `工艺路线明细` JSON供页面渲染日期行、工序行、合格行。
重复数据验证:
```powershell
EXEC dbo.[生产管理_及时齐套跟踪结果_查询] @订单号=7134, ...
```
结果:
- 返回同一生产订单号 `7134` 的二级明细 1 条。
- 不再出现同一生产订单号多条重复数据。
外购一级数据验证:
```powershell
EXEC dbo.[生产管理_及时齐套跟踪结果_查询] @订单号=7335, ...
```
结果:
- 返回 `SAP单据=7335`
- 一级数据已按 `SAP.DocEntry=7335` 匹配到计划用表/MES 计划数据。
构建验证:
```powershell
npm run build
```
结果:
- 构建通过。
- webpack compiled with 2 warnings。
- 警告仍为项目既有资源体积过大和 Browserslist/caniuse-lite 数据过期。
## 第 3 轮修正验证
重新发布查询过程:
```powershell
sqlcmd -S 192.168.2.92 -d YL_MESDB -U sa -P ****** -f 65001 -i db_backups\create_timely_kit_tracking_result_20260629.sql
```
结果:
- 执行成功。
样例 `2007` 验证:
```powershell
EXEC dbo.[生产管理_及时齐套跟踪结果_查询] @订单号=2007;
```
结果:
- 一级主数据返回 `订单号=2007``产品编码=214-YGSA200001``产品名称=过滤器组件`
- 外购缺件为 `24112-011-HY-WF50L`
- 缺件生产订单号不再显示为主订单号 `2007`
- 外购采购状态显示采购员、采购未清数量、到货草稿、质检状态。
样例 `7321` 验证:
```powershell
EXEC dbo.[生产管理_及时齐套跟踪结果_查询] @订单号=7321;
```
结果:
- 外购缺件 `XX-YG01013990` 的到货草稿为 `11209`
- 缺件生产订单号显示 `11209`
- 质检状态按采购入库检口径显示 `未完成`
默认查询统计:
```text
总行数198
产品编码/产品名称为空行数0
缺件生产订单号等于主订单号行数0
非外购质检状态非空行数0
```
前端构建:
```powershell
npm run build
```
结果:
- 构建通过。
- webpack compiled with 2 warnings。
- 警告为项目既有资源体积过大和 Browserslist/caniuse-lite 数据过期。

View File

@@ -0,0 +1,73 @@
# 06-决策记录
## DR-001 页面放在计划排产模块
- 决策:页面路径使用 `src/views/PlanManagement/TimelyKitTrackingResult/index.vue`,菜单挂在“计划排产”模块下。
- 原因:需求明确一级字段和过滤条件按“计划用表”一致,而“计划用表”属于 `PlanManagement`
- 影响:菜单权限按“计划用表”复制,避免误开放给没有计划排产权限的角色。
## DR-002 查询过程整合 SAP 缺件和 MES 计划
- 决策:新增独立过程 `dbo.生产管理_及时齐套跟踪结果_查询`,不直接改“计划用表”原过程。
- 原因:新页面有大量二级缺件追踪字段,直接改 `计划排产_查询计划信息` 会影响既有页面。
- 影响:后续口径调整集中在新过程,不影响计划用表。
## DR-003 外购件属性为空时按采购状态展示
- 决策SAP `属性` 为空时显示为“外购”,生产订单号取 SAP `在制采购`,工艺路线列拼接采购员、采购未清数量、到货草稿、质检状态。
- 原因:需求明确“属性为空时取值 SAP 视图.在制采购”,并要求外购显示采购相关字段。
- 影响:外购件不会显示当前序;如果业务后续要求外购也关联 MES 订单,需要新增匹配规则。
## DR-004 自制件按属性区分匹配规则
- 决策:机加件用 SAP `ItemCode` 匹配 MES `物料编号`;装配件用 SAP `ItemCode + Project` 匹配 MES `物料编号 + 合同号`
- 原因:需求原文明确机加和装配的匹配条件不同。
- 影响SAP `Project` 与 MES 合同号不一致时,装配件可能匹配不到 MES 计划。
## DR-005 二级数据用展开表承载
- 决策:主表按订单/产品汇总,缺件明细放到 `el-table-column type="expand"` 的二级表中。
- 原因:需求区分一级数据和绿色二级数据,展开表能避免主表过宽,同时保留所有缺件明细。
- 影响:导出或打印如果需要平铺明细,后续需要另加导出功能。
## DR-006 QUOTED_IDENTIFIER 显式设置
- 决策:查询过程脚本显式设置 `SET ANSI_NULLS ON``SET QUOTED_IDENTIFIER ON`
- 原因:过程使用 XML `.value()` 处理工艺路线拼接SQL Server 对相关 SET 选项有要求。
- 影响:后续重建该过程必须保留这些 SET 选项。
## DR-007 外购一级数据按 SAP DocEntry 匹配
- 决策SAP `属性` 为空时,使用 `SAP.DocEntry` 作为订单编号匹配计划用表/MES 计划数据。
- 原因:用户明确指出外购一级数据不应取 `在制采购`,应取 SAP 视图 `DocEntry`
- 影响:外购件的一级字段会尽量从对应 MES 计划订单读取;`在制采购` 不再作为一级匹配订单号。
## DR-008 二级同生产订单号去重
- 决策:最终查询结果按 `订单号 + 缺件生产订单号` 做去重,只保留缺件数量最大的一条。
- 原因:业务要求二级数据里不应出现生产订单号一样的数据。
- 影响:如果同一生产订单号下确实有多个不同 SAP 行,页面只展示汇总代表行;后续若要展示多 SAP 行,需要改为汇总数量而不是逐行显示。
## DR-009 工艺路线由结构化 JSON 驱动
- 决策:查询过程新增 `工艺路线明细` JSON前端据此渲染日期行、工序行、合格行和颜色。
- 原因:纯文本工艺路线无法满足计划用表式的日期、合格数和颜色展示。
- 影响:前端展示依赖 SQL Server `FOR JSON PATH` 输出;旧字段 `工艺路线` 保留作为无明细时的降级文本。
## DR-010 一级主数据必须来自计划用表
- 决策:及时齐套跟踪结果的一级主数据必须匹配 `View_生产订单_MES`,不允许用 SAP 缺件字段兜底生成主数据。
- 原因页面主表代表计划用表主订单SAP 缺件只能作为缺件明细来源;兜底会产生产品编码、计划数量、日期等字段缺失的假主数据。
- 影响:默认查询不再出现产品字段为空的主数据行。
## DR-011 外购缺件生产订单号不使用主订单号
- 决策:外购属性为空时,二级缺件生产订单号使用采购入库检侧的到货草稿;没有到货草稿时留空。
- 原因:主订单号表示一级产品订单,不能同时作为外购缺件订单号,否则会出现“主数据缺件是主数据自身”的误解。
- 影响:`2007` 这类外购缺件不再显示缺件生产订单号等于主订单号。
## DR-012 外购质检状态按采购入库检任务判断
- 决策:外购质检状态按 `SAP.到货草稿 -> 质量检验_质检任务_SAP.订单编号 -> YL_质量检验_质检记录` 判断。
- 原因:采购入库检页面的生产订单字段来自 `质量检验_质检任务_SAP.订单编号`,状态由入库数量与来料检验数量决定。
- 影响:有到货草稿的外购缺件能展示采购入库检口径的未完成/已完成;非外购不显示采购质检状态。

View File

@@ -0,0 +1,17 @@
# 新增及时齐套跟踪结果 README
## 索引
| 文件 | 用途 |
| --- | --- |
| `新增及时齐套跟踪结果.docx` | 原始需求文档副本 |
| `01-项目功能内容.md` | 页面功能范围、字段来源和数据口径 |
| `02-项目程序开发详细步骤.md` | 前端、数据库、菜单和验证步骤 |
| `03-推进台账.md` | 每轮做了什么、改了哪些文件、验证了什么、下一步是什么 |
| `04-任务矩阵.md` | 任务编号、状态、验收标准 |
| `05-验收证据.md` | 命令、页面、SQL、构建等证据 |
| `06-决策记录.md` | 关键实现决策与原因 |
## 后续推进方式
后续继续该任务时,先看 `04-任务矩阵.md` 中状态为“待办”或“观察”的任务,再按 `03-推进台账.md` 追加新轮次。涉及数据库口径调整时,新增 `db_backups` 增量脚本,不直接覆盖历史脚本。