From 192824ea90dd22db39ecf05af255918fbcbc8397 Mon Sep 17 00:00:00 2001 From: Zones <765289303@qq.com> Date: Wed, 26 Aug 2026 19:13:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=89=E5=85=A8=E5=B7=A1=E6=A3=80=E6=8E=A5?= =?UTF-8?q?=E5=85=A5=E7=9C=9F=E5=AE=9E=E6=95=B0=E6=8D=AE=E5=BA=93=EF=BC=9A?= =?UTF-8?q?=E7=BC=96=E7=A0=81=E5=AD=97=E6=AE=B5=E8=87=AA=E5=8A=A8=E7=94=9F?= =?UTF-8?q?=E6=88=90=E3=80=81=E5=85=AC=E7=A4=BA=E7=89=8C=E4=BA=8C=E7=BB=B4?= =?UTF-8?q?=E7=A0=81=E4=BF=AE=E5=A4=8D=E3=80=81=E5=AE=89=E5=85=A8=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E7=BB=9F=E8=AE=A1=E6=8E=92=E9=99=A4=E4=BD=9C=E5=BA=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 安全巡检表新增编码字段(Code,全局唯一 XJ-序号),WebAPI/桌面端新增时自动生成,不可重复 - 修复危大超危工程公示牌二维码不显示:urlName 含非法字符?导致 image.Save 抛异常,改用主键+内容哈希安全文件名 - 安全问题统计(mainProject/main3)排除作废数据(States=4),图表口径与顶部计数一致 - Word 导出文件名改为 监督巡视部位+编号 - Model.cs 由 SqlMetal 重新生成,补齐巡检人ID/签收人ID/发现问题/处理要求等字段;新增 HSSE_SafetyPatrol.Code.cs 补充 Code 列 - 新增安全巡检完整建表脚本(SGGLDB_V2026-08-25-001);删除已过时的接口文档 SafetyPatrol_API.md --- .../版本日志/SGGLDB_V2026-08-25-001-zones.sql | 140 +++++ SGGL/BLL/API/HSSE/APISafetyPatrolService.cs | 75 ++- SGGL/BLL/BLL.csproj | 1 + SGGL/BLL/Common/Const.cs | 4 + SGGL/BLL/HSSE/Hazard/SafetyPatrolService.cs | 45 +- .../HSSE/Hazard/SafetyPatrolWordService.cs | 500 ++++++++++++++++++ .../App_GlobalResources/Lan.designer.cs | 2 +- .../App_GlobalResources/Lan.resx | 2 +- .../App_GlobalResources/Lan.zh-CN.resx | 8 +- .../FineUIPro.Web/Controls/SeeQRImage.aspx.cs | 3 +- .../Controls/ShowQRImage.aspx.cs | 3 +- SGGL/FineUIPro.Web/FineUIPro.Web.csproj | 1 + .../HSSE/HazardousMG/HazardProject.aspx.cs | 10 +- .../HSSE/HazardousMG/SafetyPatrol.aspx | 36 +- .../HSSE/HazardousMG/SafetyPatrol.aspx.cs | 130 ++++- .../HSSE/HazardousMG/SafetyPatrolEdit.aspx | 212 +++++--- .../HSSE/HazardousMG/SafetyPatrolEdit.aspx.cs | 205 ++++++- .../SafetyPatrolEdit.aspx.designer.cs | 82 ++- SGGL/FineUIPro.Web/common/Menu_CQMS.xml | 1 - SGGL/FineUIPro.Web/common/main3.aspx.cs | 2 +- SGGL/FineUIPro.Web/common/mainProject.aspx.cs | 2 +- SGGL/Model/APIItem/HSSE/SafetyPatrolItem.cs | 89 +++- SGGL/Model/HSSE_SafetyPatrol.Code.cs | 18 + SGGL/Model/Model.cs | 168 ++++++ SGGL/Model/Model.csproj | 1 + .../HazardousMG/SafetyPatrolController.cs | 2 + SGGL/WebAPI/SafetyPatrol_API.md | 168 ------ 27 files changed, 1601 insertions(+), 309 deletions(-) create mode 100644 DataBase/版本日志/SGGLDB_V2026-08-25-001-zones.sql create mode 100644 SGGL/BLL/HSSE/Hazard/SafetyPatrolWordService.cs create mode 100644 SGGL/Model/HSSE_SafetyPatrol.Code.cs delete mode 100644 SGGL/WebAPI/SafetyPatrol_API.md diff --git a/DataBase/版本日志/SGGLDB_V2026-08-25-001-zones.sql b/DataBase/版本日志/SGGLDB_V2026-08-25-001-zones.sql new file mode 100644 index 0000000..d27d66a --- /dev/null +++ b/DataBase/版本日志/SGGLDB_V2026-08-25-001-zones.sql @@ -0,0 +1,140 @@ +-- ===================================================================== +-- 安全巡检记录表(危大、超危工程 监督记录) +-- 说明:监督巡视部位即工程名称(取自危大、超危工程 HazardProjectName), +-- 不再单独存 PatrolLocation 列。 +-- 本脚本:表存在则删除重建,含全部字段、主键与中文列注释,可直接执行。 +-- ===================================================================== +-- 如果表存在直接删除 +DROP TABLE IF EXISTS [dbo].[HSSE_SafetyPatrol]; +GO + +CREATE TABLE [dbo].[HSSE_SafetyPatrol] ( + [PatrolId] nvarchar(50) COLLATE Chinese_PRC_CI_AS NOT NULL, + [ProjectId] nvarchar(50) COLLATE Chinese_PRC_CI_AS NOT NULL, + [HazardProjectId] nvarchar(50) COLLATE Chinese_PRC_CI_AS NULL, + [HazardProjectName] nvarchar(500) COLLATE Chinese_PRC_CI_AS NULL, + [PatrolDate] datetime NULL, + [PatrolMan] nvarchar(50) COLLATE Chinese_PRC_CI_AS NULL, + [PatrolManId] nvarchar(50) COLLATE Chinese_PRC_CI_AS NULL, + [PatrolStatus] nvarchar(50) COLLATE Chinese_PRC_CI_AS NULL, + [Content] nvarchar(1000) COLLATE Chinese_PRC_CI_AS NULL, + [Problems] nvarchar(1000) COLLATE Chinese_PRC_CI_AS NULL, + [Receiver] nvarchar(50) COLLATE Chinese_PRC_CI_AS NULL, + [ReceiverId] nvarchar(50) COLLATE Chinese_PRC_CI_AS NULL, + [HandleRequire] nvarchar(1000) COLLATE Chinese_PRC_CI_AS NULL, + [RectifyReview] nvarchar(1000) COLLATE Chinese_PRC_CI_AS NULL, + [Remarks] nvarchar(500) COLLATE Chinese_PRC_CI_AS NULL, + [Code] nvarchar(50) COLLATE Chinese_PRC_CI_AS NULL, + CONSTRAINT [PK_HSSE_SafetyPatrol] PRIMARY KEY CLUSTERED ([PatrolId]) +) ON [PRIMARY] +GO + +ALTER TABLE [dbo].[HSSE_SafetyPatrol] SET (LOCK_ESCALATION = TABLE) +GO + +EXEC sp_addextendedproperty +'MS_Description', N'安全巡检记录', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol' +GO +EXEC sp_addextendedproperty +'MS_Description', N'主键', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol', +'COLUMN', N'PatrolId' +GO +EXEC sp_addextendedproperty +'MS_Description', N'项目', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol', +'COLUMN', N'ProjectId' +GO +EXEC sp_addextendedproperty +'MS_Description', N'危大、超危工程', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol', +'COLUMN', N'HazardProjectId' +GO +EXEC sp_addextendedproperty +'MS_Description', N'监督巡视部位(即工程名称)', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol', +'COLUMN', N'HazardProjectName' +GO +EXEC sp_addextendedproperty +'MS_Description', N'巡检日期', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol', +'COLUMN', N'PatrolDate' +GO +EXEC sp_addextendedproperty +'MS_Description', N'巡检人名称(监督巡视人员)', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol', +'COLUMN', N'PatrolMan' +GO +EXEC sp_addextendedproperty +'MS_Description', N'巡检人ID', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol', +'COLUMN', N'PatrolManId' +GO +EXEC sp_addextendedproperty +'MS_Description', N'巡检状态(正常/待整改/整改待复查)', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol', +'COLUMN', N'PatrolStatus' +GO +EXEC sp_addextendedproperty +'MS_Description', N'巡视内容(勾选项与其它拼接文本)', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol', +'COLUMN', N'Content' +GO +EXEC sp_addextendedproperty +'MS_Description', N'发现问题', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol', +'COLUMN', N'Problems' +GO +EXEC sp_addextendedproperty +'MS_Description', N'签收人名称', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol', +'COLUMN', N'Receiver' +GO +EXEC sp_addextendedproperty +'MS_Description', N'签收人ID', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol', +'COLUMN', N'ReceiverId' +GO +EXEC sp_addextendedproperty +'MS_Description', N'处理要求', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol', +'COLUMN', N'HandleRequire' +GO +EXEC sp_addextendedproperty +'MS_Description', N'整改后复查情况', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol', +'COLUMN', N'RectifyReview' +GO +EXEC sp_addextendedproperty +'MS_Description', N'备注', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol', +'COLUMN', N'Remarks' +GO +EXEC sp_addextendedproperty +'MS_Description', N'编码(全局唯一,格式 XJ-序号,自动生成)', +'SCHEMA', N'dbo', +'TABLE', N'HSSE_SafetyPatrol', +'COLUMN', N'Code' +GO + +-- 编码唯一索引 +CREATE UNIQUE INDEX [UX_HSSE_SafetyPatrol_Code] + ON [dbo].[HSSE_SafetyPatrol] ([Code]) +GO diff --git a/SGGL/BLL/API/HSSE/APISafetyPatrolService.cs b/SGGL/BLL/API/HSSE/APISafetyPatrolService.cs index 5b90ff6..dbe7084 100644 --- a/SGGL/BLL/API/HSSE/APISafetyPatrolService.cs +++ b/SGGL/BLL/API/HSSE/APISafetyPatrolService.cs @@ -29,13 +29,21 @@ namespace BLL select new Model.SafetyPatrolItem { PatrolId = x.PatrolId, + Code = x.Code, ProjectId = x.ProjectId, HazardProjectId = x.HazardProjectId, HazardProjectName = x.HazardProjectName, PatrolDate = x.PatrolDate, PatrolMan = x.PatrolMan, + PatrolManId = x.PatrolManId, PatrolStatus = x.PatrolStatus, - Content = x.Content + Content = x.Content, + Problems = x.Problems, + Receiver = x.Receiver, + ReceiverId = x.ReceiverId, + HandleRequire = x.HandleRequire, + RectifyReview = x.RectifyReview, + Remarks = x.Remarks }; return list.ToList(); } @@ -58,13 +66,21 @@ namespace BLL return new Model.SafetyPatrolItem { PatrolId = x.PatrolId, + Code = x.Code, ProjectId = x.ProjectId, HazardProjectId = x.HazardProjectId, HazardProjectName = x.HazardProjectName, PatrolDate = x.PatrolDate, PatrolMan = x.PatrolMan, + PatrolManId = x.PatrolManId, PatrolStatus = x.PatrolStatus, - Content = x.Content + Content = x.Content, + Problems = x.Problems, + Receiver = x.Receiver, + ReceiverId = x.ReceiverId, + HandleRequire = x.HandleRequire, + RectifyReview = x.RectifyReview, + Remarks = x.Remarks }; } } @@ -82,16 +98,29 @@ namespace BLL } using (Model.SGGLDB db = new Model.SGGLDB(Funs.ConnString)) { + ////编码为空时自动生成(全局唯一) + if (string.IsNullOrEmpty(item.Code)) + { + item.Code = GetNewCode(db); + } Model.HSSE_SafetyPatrol newItem = new Model.HSSE_SafetyPatrol { PatrolId = item.PatrolId, + Code = item.Code, ProjectId = item.ProjectId, HazardProjectId = item.HazardProjectId, HazardProjectName = item.HazardProjectName, PatrolDate = item.PatrolDate, PatrolMan = item.PatrolMan, + PatrolManId = item.PatrolManId, PatrolStatus = item.PatrolStatus, - Content = item.Content + Content = item.Content, + Problems = item.Problems, + Receiver = item.Receiver, + ReceiverId = item.ReceiverId, + HandleRequire = item.HandleRequire, + RectifyReview = item.RectifyReview, + Remarks = item.Remarks }; db.HSSE_SafetyPatrol.InsertOnSubmit(newItem); db.SubmitChanges(); @@ -101,6 +130,11 @@ namespace BLL { APIUpLoadFileService.SaveAttachUrl(Const.SafetyPatrolMenuId, item.PatrolId, item.AttachUrl, "0"); } + ////保存整改图片附件 + if (!string.IsNullOrEmpty(item.RectifyAttachUrl)) + { + APIUpLoadFileService.SaveAttachUrl(Const.SafetyPatrolRectifyMenuId, item.PatrolId, item.RectifyAttachUrl, "0"); + } return item.PatrolId; } @@ -123,8 +157,15 @@ namespace BLL newItem.HazardProjectName = item.HazardProjectName; newItem.PatrolDate = item.PatrolDate; newItem.PatrolMan = item.PatrolMan; + newItem.PatrolManId = item.PatrolManId; newItem.PatrolStatus = item.PatrolStatus; newItem.Content = item.Content; + newItem.Problems = item.Problems; + newItem.Receiver = item.Receiver; + newItem.ReceiverId = item.ReceiverId; + newItem.HandleRequire = item.HandleRequire; + newItem.RectifyReview = item.RectifyReview; + newItem.Remarks = item.Remarks; db.SubmitChanges(); } ////保存巡检图片附件 @@ -132,7 +173,35 @@ namespace BLL { APIUpLoadFileService.SaveAttachUrl(Const.SafetyPatrolMenuId, item.PatrolId, item.AttachUrl, "0"); } + ////保存整改图片附件 + if (!string.IsNullOrEmpty(item.RectifyAttachUrl)) + { + APIUpLoadFileService.SaveAttachUrl(Const.SafetyPatrolRectifyMenuId, item.PatrolId, item.RectifyAttachUrl, "0"); + } return true; } + + /// + /// 生成新的巡检编码(全局唯一,前缀 XJ-,三位递增序号) + /// + /// 数据库上下文 + /// + private static string GetNewCode(Model.SGGLDB db) + { + int max = 0; + foreach (Model.HSSE_SafetyPatrol item in db.HSSE_SafetyPatrol.ToList()) + { + string code = item.Code; + if (!string.IsNullOrEmpty(code) && code.StartsWith("XJ-")) + { + int num = 0; + if (int.TryParse(code.Substring(3), out num) && num > max) + { + max = num; + } + } + } + return string.Format("XJ-{0:D3}", max + 1); + } } } diff --git a/SGGL/BLL/BLL.csproj b/SGGL/BLL/BLL.csproj index 5173c0e..c7bda8e 100644 --- a/SGGL/BLL/BLL.csproj +++ b/SGGL/BLL/BLL.csproj @@ -576,6 +576,7 @@ + diff --git a/SGGL/BLL/Common/Const.cs b/SGGL/BLL/Common/Const.cs index d007ae8..a59b66a 100644 --- a/SGGL/BLL/Common/Const.cs +++ b/SGGL/BLL/Common/Const.cs @@ -2607,6 +2607,10 @@ namespace BLL /// public const string SafetyPatrolMenuId = "3EE924B8-DFB2-47DA-ADC1-FF8190E214F1"; /// + /// 安全巡检整改图片 + /// + public const string SafetyPatrolRectifyMenuId = "29A1CA62-7D69-4F1C-84BA-F5D7125289F5"; + /// /// 作业票申请 /// public const string ProjectLicenseApplyMenuId = "2E58D4F1-2FF1-450E-8A00-1CE3BBCF8D5B"; diff --git a/SGGL/BLL/HSSE/Hazard/SafetyPatrolService.cs b/SGGL/BLL/HSSE/Hazard/SafetyPatrolService.cs index 7a10a64..3a33d04 100644 --- a/SGGL/BLL/HSSE/Hazard/SafetyPatrolService.cs +++ b/SGGL/BLL/HSSE/Hazard/SafetyPatrolService.cs @@ -29,6 +29,28 @@ namespace BLL return Funs.DB.HSSE_SafetyPatrol.FirstOrDefault(x => x.PatrolId == patrolId); } + /// + /// 获取新编码(全局唯一,前缀 XJ-,三位递增序号,如 XJ-001) + /// + /// + public static string GetNewCode() + { + int max = 0; + foreach (Model.HSSE_SafetyPatrol item in Funs.DB.HSSE_SafetyPatrol.ToList()) + { + string code = item.Code; + if (!string.IsNullOrEmpty(code) && code.StartsWith("XJ-")) + { + int num = 0; + if (int.TryParse(code.Substring(3), out num) && num > max) + { + max = num; + } + } + } + return string.Format("XJ-{0:D3}", max + 1); + } + /// /// 新增安全巡检记录 /// @@ -36,16 +58,30 @@ namespace BLL public static void Add(Model.HSSE_SafetyPatrol item) { Model.SGGLDB db = Funs.DB; + ////编码为空时自动生成(全局唯一) + string code = item.Code; + if (string.IsNullOrEmpty(code)) + { + code = GetNewCode(); + } Model.HSSE_SafetyPatrol newItem = new Model.HSSE_SafetyPatrol { PatrolId = item.PatrolId, + Code = code, ProjectId = item.ProjectId, HazardProjectId = item.HazardProjectId, HazardProjectName = item.HazardProjectName, PatrolDate = item.PatrolDate, PatrolMan = item.PatrolMan, + PatrolManId = item.PatrolManId, PatrolStatus = item.PatrolStatus, - Content = item.Content + Content = item.Content, + Problems = item.Problems, + Receiver = item.Receiver, + ReceiverId = item.ReceiverId, + HandleRequire = item.HandleRequire, + RectifyReview = item.RectifyReview, + Remarks = item.Remarks }; db.HSSE_SafetyPatrol.InsertOnSubmit(newItem); db.SubmitChanges(); @@ -65,8 +101,15 @@ namespace BLL newItem.HazardProjectName = item.HazardProjectName; newItem.PatrolDate = item.PatrolDate; newItem.PatrolMan = item.PatrolMan; + newItem.PatrolManId = item.PatrolManId; newItem.PatrolStatus = item.PatrolStatus; newItem.Content = item.Content; + newItem.Problems = item.Problems; + newItem.Receiver = item.Receiver; + newItem.ReceiverId = item.ReceiverId; + newItem.HandleRequire = item.HandleRequire; + newItem.RectifyReview = item.RectifyReview; + newItem.Remarks = item.Remarks; db.SubmitChanges(); } else diff --git a/SGGL/BLL/HSSE/Hazard/SafetyPatrolWordService.cs b/SGGL/BLL/HSSE/Hazard/SafetyPatrolWordService.cs new file mode 100644 index 0000000..e65c5e8 --- /dev/null +++ b/SGGL/BLL/HSSE/Hazard/SafetyPatrolWordService.cs @@ -0,0 +1,500 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Drawing; +using System.IO; +using System.Linq; +using Aspose.Words; +using Aspose.Words.Tables; + +namespace BLL +{ + /// + /// 安全巡检——导出监督记录表 Word + /// + public static class SafetyPatrolWordService + { + /// + /// 生成附件9《(危大工程类别)监督记录表》Word 文档(.docx) + /// + /// 巡检记录主键 + /// docx 字节流;记录不存在返回 null + public static byte[] Generate(string patrolId) + { + Model.HSSE_SafetyPatrol info = SafetyPatrolService.GetById(patrolId); + if (info == null) + { + return null; + } + + Document doc = new Document(); + DocumentBuilder b = new DocumentBuilder(doc); + AppendRecord(b, info); + + ApplyFonts(doc); + ApplyLineSpacing(doc); + + MemoryStream ms = new MemoryStream(); + doc.Save(ms, SaveFormat.Docx); + return ms.ToArray(); + } + + /// + /// 写入单独一条(标题 + 记录表) + /// + /// 文档构建器 + /// 巡检记录 + private static void AppendRecord(DocumentBuilder b, Model.HSSE_SafetyPatrol info) + { + ////全局默认字体 + b.Font.Name = "微软雅黑"; + b.Font.NameFarEast = "微软雅黑"; + b.Font.Size = 10.5; + + ////固定页面为 A4,保证表格宽度不会被压缩(A4 内容宽 = 595 - 40 - 40 = 515 磅) + PageSetup ps = b.Document.FirstSection.PageSetup; + ps.PageWidth = 595; + ps.PageHeight = 842; + ps.LeftMargin = 40; + ps.RightMargin = 40; + ps.TopMargin = 40; + ps.BottomMargin = 40; + + ////标题(附件9) + b.ParagraphFormat.Alignment = ParagraphAlignment.Center; + b.Font.Size = 16; + b.Font.Bold = true; + b.Write("附件9 (危大工程类别)监督记录表"); + b.ParagraphFormat.SpaceAfter = 30; // 标题与下方「监督巡视部位」之间留 40px ≈ 30pt + b.Writeln(); + b.Font.Bold = false; + b.Font.Size = 10.5; + b.ParagraphFormat.SpaceAfter = 0; // 还原,避免影响后续段落 + b.ParagraphFormat.Alignment = ParagraphAlignment.Left; + + ////监督巡视部位 / 巡视日期:拆成左右两列、各占一行 50%(无边框), + ////与下方记录表同宽(412 磅、居中,两列各 206 磅),保证与表格两列精确对齐。 + Table head = b.StartTable(); + b.CellFormat.VerticalAlignment = CellVerticalAlignment.Center; + b.CellFormat.Width = 206; + b.InsertCell(); + b.Write("监督巡视部位:" + (info.HazardProjectName ?? "")); + b.CellFormat.Width = 206; + b.InsertCell(); + b.Write("巡视日期:" + (info.PatrolDate.HasValue ? info.PatrolDate.Value.ToString("yyyy-MM-dd") : "")); + b.EndRow(); + b.EndTable(); + + ////无边框 + 定宽居中,使两列与下方记录表的起止完全对齐 + head.AllowAutoFit = false; + head.PreferredWidth = PreferredWidth.FromPoints(412); + head.Alignment = TableAlignment.Center; + head.Rows[0].Cells[0].CellFormat.Width = 206; + head.Rows[0].Cells[1].CellFormat.Width = 206; + ////默认表格无边框;个别环境下若带边框则显式清空 + foreach (Cell c in head.Rows[0].Cells) + { + foreach (Border bd in c.CellFormat.Borders) + { + bd.LineStyle = LineStyle.None; + } + } + + ////记录表主体:统一两列(左=标签/内容区,右=发现问题/签收人/空),每行都是独立单元格。 + ////重要:不要用 VerticalMerge 或全宽 gridSpan —— DocumentBuilder 无法可靠地只合并右列, + ////会把左列下部的「处理要求/整改后复查/备注」吞掉或把表格网格弄乱。统一两列最稳定。 + Table table = b.StartTable(); + b.CellFormat.VerticalAlignment = CellVerticalAlignment.Center; + + ////行1:表头 监督巡视内容 | 发现问题 + b.CellFormat.Width = 340; + b.InsertCell(); + b.Write("监督巡视内容"); + b.CellFormat.Width = 175; + b.InsertCell(); + b.Write("发现问题"); + b.EndRow(); + + ////行3:勾选项(固定4项+其它) | 发现问题内容 + b.CellFormat.Width = 340; + b.InsertCell(); + WriteContentLines(b, info.Content); + b.CellFormat.Width = 175; + b.InsertCell(); + b.Write(info.Problems ?? ""); + b.EndRow(); + + ////行4:处理要求: | 签收人: + b.CellFormat.Width = 340; + b.InsertCell(); + b.Write("处理要求:"); + b.CellFormat.Width = 175; + b.InsertCell(); + b.Write("签收人:" + (string.IsNullOrEmpty(info.Receiver) ? "____________" : info.Receiver)); + b.EndRow(); + + ////行5:处理要求内容区(占3行),整格横向合并(横跨两列) + b.CellFormat.Width = 340; + b.InsertCell(); + WriteArea(b, info.HandleRequire, 3); + b.CellFormat.Width = 175; + b.InsertCell(); + b.EndRow(); + + ////行6-7:整改后复查情况 + 内容区,合并为一个整宽纵向单元格。 + ////重要:纵并组里只有 restart 格(上半行)的正文会显示,continue 格必须留空, + ////因此把「标签:」与内容都写入 restart 格。 + b.CellFormat.Width = 340; + b.InsertCell(); + WriteLabelArea(b, "整改后复查情况:", info.RectifyReview, 5); + b.CellFormat.Width = 175; + b.InsertCell(); + b.EndRow(); + + ////行7:纵并 continue 格(留空) + b.CellFormat.Width = 340; + b.InsertCell(); + b.Writeln(); + b.CellFormat.Width = 175; + b.InsertCell(); + b.Writeln(); + b.EndRow(); + + ////行8-9:备注 + 内容区,合并为一个整宽纵向单元格 + b.CellFormat.Width = 340; + b.InsertCell(); + WriteLabelArea(b, "备注:", info.Remarks, 2); + b.CellFormat.Width = 175; + b.InsertCell(); + b.EndRow(); + + ////行9:纵并 continue 格(留空) + b.CellFormat.Width = 340; + b.InsertCell(); + b.Writeln(); + b.CellFormat.Width = 175; + b.InsertCell(); + b.Writeln(); + b.EndRow(); + + b.EndTable(); + + ////表格宽度:占内容区 80%(515 × 0.8 = 412 磅),并水平居中 + table.AllowAutoFit = false; + table.PreferredWidth = PreferredWidth.FromPoints(412); + table.Alignment = TableAlignment.Center; + double cellWidth = 412 / 2.0; // 两列等宽 = 206 磅 + foreach (Row row in table.Rows) + { + row.Cells[0].CellFormat.Width = cellWidth; // 左列 + row.Cells[1].CellFormat.Width = cellWidth; // 右列(与左列等宽) + } + ////发现问题内容(行1右列):左上显示,不垂直居中。 + ////DocumentBuilder 中途设置 CellFormat.VerticalAlignment 对当前单元格不生效, + ////必须在 post-build 阶段用 Cell 对象设置(与合并同一方式)。 + table.Rows[1].Cells[1].CellFormat.VerticalAlignment = CellVerticalAlignment.Top; + + ////整宽 / 跨行合并:post-build 阶段用 Cell 对象合并,gridCol 仍保持两列。 + ////表头之下共 8 行:索引0=表头,1=发现问题,2=处理要求/签收人, + ////索引3=处理要求内容区(横并),索引4-5=整改后复查(纵并+整宽),索引6-7=备注(纵并+整宽)。 + HorizontalMergeRow(table.Rows[3]); + HorizontalMergeRow(table.Rows[4]); VerticalMergeTop(table.Rows[4]); + HorizontalMergeRow(table.Rows[5]); VerticalMergeBottom(table.Rows[5]); + HorizontalMergeRow(table.Rows[6]); VerticalMergeTop(table.Rows[6]); + HorizontalMergeRow(table.Rows[7]); VerticalMergeBottom(table.Rows[7]); + + ////表格样式:细黑色网格线(与图片一致) + table.StyleIdentifier = StyleIdentifier.TableGrid; + + ////底部:监督巡视人员(恢复正文大小,签收人已入表格第4行右列) + ////右对齐到表格右缘:右缩进 51.5 磅(= 表格居中后右侧留白) + b.Font.Size = 10.5; + b.Font.Bold = false; + b.ParagraphFormat.Alignment = ParagraphAlignment.Right; + b.ParagraphFormat.LeftIndent = 51.5; + b.ParagraphFormat.RightIndent = 51.5; + b.Write("监督巡视人员:" + (info.PatrolMan ?? "")); + b.Writeln(); + + ////注:左对齐到表格左缘(左缩进 51.5 磅),还原右对齐/右缩进 + b.ParagraphFormat.Alignment = ParagraphAlignment.Left; + b.ParagraphFormat.RightIndent = 0; + b.Write("注:此表可优化调整,但管理要素不得少于上表。"); + b.Writeln(); + + ////巡检附件 / 整改附件:另起一页显示(第二页起) + b.InsertBreak(BreakType.PageBreak); + AppendAttachments(b, info.PatrolId); + } + + /// + /// 在第二页写入巡检附件与整改附件图片(按记录遍历,逐张缩放嵌入)。 + /// 附件图片均为磁盘文件,通过 localRoot + AttachUrl 定位;无附件则给出「无」。 + /// + /// 文档构建器 + /// 巡检记录主键 + private static void AppendAttachments(DocumentBuilder b, string patrolId) + { + if (string.IsNullOrEmpty(patrolId)) + { + return; + } + + string localRoot = ConfigurationManager.AppSettings["localRoot"] ?? string.Empty; + b.Font.Bold = false; + b.Font.Size = 10.5; + + WriteAttachSection(b, "一、巡检附件", patrolId, Const.SafetyPatrolMenuId, localRoot); + WriteAttachSection(b, "二、整改附件", patrolId, Const.SafetyPatrolRectifyMenuId, localRoot); + } + + /// + /// 写入一个附件分组:标题行 + 该分组下的所有附件图片(缩放至最大宽 412 磅保持原比例)。 + /// 非图片文件仅列出文件名;分组无附件则写「无」。 + /// + /// 文档构建器 + /// 分组标题(如「一、巡检附件」) + /// 巡检记录主键 + /// 附件菜单ID + /// 附件磁盘根目录 + private static void WriteAttachSection(DocumentBuilder b, string title, string patrolId, string menuId, string localRoot) + { + b.ParagraphFormat.Alignment = ParagraphAlignment.Left; + b.ParagraphFormat.SpaceBefore = 6; + b.Write(title); + b.Writeln(); + b.ParagraphFormat.SpaceBefore = 0; + + List files = Funs.DB.AttachFile + .Where(p => p.ToKeyId == patrolId && p.MenuId == menuId) + .ToList(); + + if (files == null || files.Count == 0) + { + b.Write("无"); + b.Writeln(); + return; + } + + foreach (Model.AttachFile f in files) + { + if (string.IsNullOrEmpty(f.AttachUrl)) + { + continue; + } + string filePath = Path.Combine(localRoot, f.AttachUrl.Replace('/', '\\')); + if (!File.Exists(filePath)) + { + continue; + } + string ext = Path.GetExtension(filePath).ToLowerInvariant(); + if (ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".gif" || ext == ".bmp") + { + b.ParagraphFormat.SpaceBefore = 4; + InsertImageScaled(b, filePath, 400, 260); + b.Writeln(); // 每张图独占一行,避免后续标题/图片内联到图右侧 + b.ParagraphFormat.SpaceBefore = 0; + } + else + { + b.Write(Path.GetFileName(filePath)); + b.Writeln(); + } + } + } + + /// + /// 插入图片:缩放至不超过指定宽高(磅),保持原始宽高比。 + /// + /// 文档构建器 + /// 图片物理路径 + /// 最大宽(磅) + /// 最大高(磅) + private static void InsertImageScaled(DocumentBuilder b, string filePath, double maxWidthPt, double maxHeightPt) + { + try + { + using (Image img = Image.FromFile(filePath)) + { + int w = img.Width; + int h = img.Height; + if (w <= 0 || h <= 0) + { + return; + } + double scale = Math.Min(maxWidthPt / w, maxHeightPt / h); + b.InsertImage(filePath, w * scale, h * scale); + } + } + catch + { + // 非图片或读取失败:忽略 + } + } + + /// + /// 写入内容区单元格:先写内容,再用空段落撑高到指定行数。 + /// 无内容时也保证最小行高,便于手写填写。 + /// + /// 文档构建器 + /// 内容 + /// 最小行数(空段落数) + private static void WriteArea(DocumentBuilder b, string text, int minLines) + { + if (!string.IsNullOrEmpty(text)) + { + b.Write(text); + } + for (int i = 0; i < minLines; i++) + { + b.Writeln(); + } + } + + /// + /// 监督巡视内容固定项(与编辑页复选框 Text 一致) + /// + private static readonly string[] PatrolContentItems = new string[] + { + "1、施工条件保持情况", + "2、按方案施工情况,实体与方案参数的对比", + "3、现场安全防护状况", + "4、作业人员持证上岗情况" + }; + + /// + /// 将监督巡视内容写入单元格:始终保持 4 个固定项(写死默认值)+ 一行「其它」。 + /// 其它:Content 字段以后只存「其它」内容,直接显示;若含「其它:」前缀则取后半段(兼容旧格式);无内容则下划线占位。 + /// + /// 文档构建器 + /// Content 文本(以后仅存其它内容,如:基坑围挡损坏;旧数据可能形如:1、…;4、…;其它:xxx) + private static void WriteContentLines(DocumentBuilder b, string content) + { + bool first = true; + + ////固定 4 项始终输出(写死默认值) + foreach (string item in PatrolContentItems) + { + if (!first) + { + b.Writeln(); + } + b.Write(item); + first = false; + } + + ////其它行:优先取 Content 中「其它:」后半段(兼容旧格式);否则 Content 即其它内容 + b.Writeln(); + string other = ExtractOther(content); + if (other.Length == 0) + { + other = content ?? string.Empty; + } + b.Write("其它:" + (other.Length > 0 ? other : "____________")); + } + + /// + /// 从 Content 文本中提取「其它」说明内容(无则返回空串) + /// + /// Content 文本 + /// 其它说明;未包含返回空串 + private static string ExtractOther(string content) + { + if (string.IsNullOrEmpty(content)) + { + return string.Empty; + } + foreach (string seg in content.Split(';')) + { + string s = seg.Trim(); + if (s.Length == 0) + { + continue; + } + if (s.StartsWith("其它") || s.StartsWith("其他")) + { + int idx = s.IndexOf(':'); + return idx >= 0 ? s.Substring(idx + 1).Trim() : string.Empty; + } + } + return string.Empty; + } + + /// + /// 将一行的左右两格横向合并为整宽单元格(gridSpan=2)。 + /// 必须在 post-build 阶段用 Cell 对象合并,避免 DocumentBuilder 把表格网格弄乱。 + /// + /// 待合并的行 + private static void HorizontalMergeRow(Row row) + { + row.Cells[0].CellFormat.HorizontalMerge = CellMerge.First; + row.Cells[1].CellFormat.HorizontalMerge = CellMerge.Previous; + } + + /// + /// 纵向合并的起始行(restart)。该行正文会被保留,并与其下方 continue 行合并为一个单元格。 + /// + /// 起始行 + private static void VerticalMergeTop(Row row) + { + row.Cells[0].CellFormat.VerticalMerge = CellMerge.First; + row.Cells[1].CellFormat.VerticalMerge = CellMerge.First; + } + + /// + /// 纵向合并的延续行(continue)。该行正文不会显示,必须留空。 + /// + /// 延续行 + private static void VerticalMergeBottom(Row row) + { + row.Cells[0].CellFormat.VerticalMerge = CellMerge.Previous; + row.Cells[1].CellFormat.VerticalMerge = CellMerge.Previous; + } + + /// + /// 写入「标签:」+ 内容区,标签独占一行,内容随后以内容/空段落撑高。 + /// 用于纵向合并单元格(标签与内容需写入 restart 格)。 + /// + /// 文档构建器 + /// 标签(如「整改后复查情况:」) + /// 内容 + /// 最小行数(空段落数) + private static void WriteLabelArea(DocumentBuilder b, string label, string text, int minLines) + { + b.Write(label); + b.Writeln(); + WriteArea(b, text, minLines); + } + + /// + /// 统一全文正文字体:仅标题「附件9 …监督记录表」加粗(16 磅),其余一律 10.5 磅、不加粗。 + /// DocumentBuilder 在跨表格书写时会丢失字符格式状态(标题的加粗/16 磅曾泄漏到记录表与落款), + /// 故在 post-build 阶段对所有 Run 兜底逐一遍历设置,保证只有标题加粗。 + /// + /// 文档 + private static void ApplyFonts(Document doc) + { + foreach (Run run in doc.GetChildNodes(NodeType.Run, true)) + { + bool isTitle = run.Text == "附件9 (危大工程类别)监督记录表"; + run.Font.Bold = isTitle; + run.Font.Size = isTitle ? 16 : 10.5; + } + } + + /// + /// 为文档中所有段落(含表格单元格内)设置 1.5 倍行距。 + /// Aspose 的 Multiple 行距以磅为单位:单倍 = 12 磅,1.5 倍 = 18 磅, + /// 生成 w:line="360" w:lineRule="auto"(360/240 = 1.5 倍)。 + /// + /// 文档 + private static void ApplyLineSpacing(Document doc) + { + foreach (Paragraph p in doc.GetChildNodes(NodeType.Paragraph, true)) + { + p.ParagraphFormat.LineSpacingRule = LineSpacingRule.Multiple; + p.ParagraphFormat.LineSpacing = 14; // 1.5 倍行距(18 磅 → w:line="360",360/240=1.5) + } + } + } +} diff --git a/SGGL/FineUIPro.Web/App_GlobalResources/Lan.designer.cs b/SGGL/FineUIPro.Web/App_GlobalResources/Lan.designer.cs index 05c5f9b..df00027 100644 --- a/SGGL/FineUIPro.Web/App_GlobalResources/Lan.designer.cs +++ b/SGGL/FineUIPro.Web/App_GlobalResources/Lan.designer.cs @@ -547,7 +547,7 @@ namespace Resources { } /// - /// 查找类似 质量管理 的本地化字符串。 + /// 查找类似 技术质量管理 的本地化字符串。 /// internal static string QualityManage { get { diff --git a/SGGL/FineUIPro.Web/App_GlobalResources/Lan.resx b/SGGL/FineUIPro.Web/App_GlobalResources/Lan.resx index 49eb719..4bc92bb 100644 --- a/SGGL/FineUIPro.Web/App_GlobalResources/Lan.resx +++ b/SGGL/FineUIPro.Web/App_GlobalResources/Lan.resx @@ -151,7 +151,7 @@ 在新标签页中打开 - 质量管理 + 技术质量管理 退出 diff --git a/SGGL/FineUIPro.Web/App_GlobalResources/Lan.zh-CN.resx b/SGGL/FineUIPro.Web/App_GlobalResources/Lan.zh-CN.resx index 2a168a2..ec73772 100644 --- a/SGGL/FineUIPro.Web/App_GlobalResources/Lan.zh-CN.resx +++ b/SGGL/FineUIPro.Web/App_GlobalResources/Lan.zh-CN.resx @@ -151,7 +151,7 @@ 在新标签页中打开 - 质量管理 + 技术质量管理 退出 @@ -201,6 +201,9 @@ 综合管理 + + 您没有权限进入项目管理模块! + 通知管理 @@ -213,9 +216,6 @@ 切换首页 - - 您没有权限进入项目管理模块! - 证书预警 diff --git a/SGGL/FineUIPro.Web/Controls/SeeQRImage.aspx.cs b/SGGL/FineUIPro.Web/Controls/SeeQRImage.aspx.cs index 5539193..bfa3fdf 100644 --- a/SGGL/FineUIPro.Web/Controls/SeeQRImage.aspx.cs +++ b/SGGL/FineUIPro.Web/Controls/SeeQRImage.aspx.cs @@ -196,10 +196,11 @@ namespace FineUIPro.Web.Controls try { string imageUrl = string.Empty; + ////QRCodeScale 为每个二维码模块的像素倍数,固定值 5(原为 nr.Length,会随内容长度放大成超大图) QRCodeEncoder qrCodeEncoder = new QRCodeEncoder { QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE, - QRCodeScale = nr.Length, + QRCodeScale = 5, QRCodeVersion = 0, QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M }; diff --git a/SGGL/FineUIPro.Web/Controls/ShowQRImage.aspx.cs b/SGGL/FineUIPro.Web/Controls/ShowQRImage.aspx.cs index a7e6e99..d9d9a7d 100644 --- a/SGGL/FineUIPro.Web/Controls/ShowQRImage.aspx.cs +++ b/SGGL/FineUIPro.Web/Controls/ShowQRImage.aspx.cs @@ -51,10 +51,11 @@ namespace FineUIPro.Web.Controls private void CreateCode_Simple(string nr, string urlName) { string imageUrl = string.Empty; + ////QRCodeScale 为每个二维码模块的像素倍数,固定值 5(原为 nr.Length,会随内容长度放大成超大图) QRCodeEncoder qrCodeEncoder = new QRCodeEncoder { QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE, - QRCodeScale = nr.Length, + QRCodeScale = 5, QRCodeVersion = 0, QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M }; diff --git a/SGGL/FineUIPro.Web/FineUIPro.Web.csproj b/SGGL/FineUIPro.Web/FineUIPro.Web.csproj index bd6e303..091a451 100644 --- a/SGGL/FineUIPro.Web/FineUIPro.Web.csproj +++ b/SGGL/FineUIPro.Web/FineUIPro.Web.csproj @@ -19843,6 +19843,7 @@ GlobalResourceProxyGenerator Lan.designer.cs + Designer diff --git a/SGGL/FineUIPro.Web/HSSE/HazardousMG/HazardProject.aspx.cs b/SGGL/FineUIPro.Web/HSSE/HazardousMG/HazardProject.aspx.cs index 83d0cac..58eb2c8 100644 --- a/SGGL/FineUIPro.Web/HSSE/HazardousMG/HazardProject.aspx.cs +++ b/SGGL/FineUIPro.Web/HSSE/HazardousMG/HazardProject.aspx.cs @@ -330,10 +330,14 @@ namespace FineUIPro.Web.HSSE.HazardousMG if (info != null) { ////二维码内容:危大工程标识(编号),接入数据库后替换为巡检页面URL - string strValue = "hazard$hid=" + info.HazardProjectId; - string urlName = "hazard$hid=" + info.HazardProjectId; + string strValue = "hazard$hid=" + info.HazardProjectId + "&hname=" + info.ProjectName + "&projectId=" + info.ProjectId; + ////urlName 仅作生成的二维码图片文件名,用「主键+内容哈希」保证文件名安全(不含 ? / = 等非法字符)且内容变化时不复用旧图 + string urlName = info.HazardProjectId + "_" + ((uint)strValue.GetHashCode()).ToString("X"); string title = "危大工程公示牌:" + info.ProjectName; - PageContext.RegisterStartupScript(Window1.GetShowReference(String.Format("~/Controls/ShowQRImage.aspx?strValue={0}&urlName={1}&title={2}", strValue, urlName, System.Web.HttpUtility.UrlEncode(title)), "公示牌二维码", 340, 400)); + PageContext.RegisterStartupScript(Window1.GetShowReference(String.Format("~/Controls/ShowQRImage.aspx?strValue={0}&urlName={1}&title={2}", + System.Web.HttpUtility.UrlEncode(strValue), + System.Web.HttpUtility.UrlEncode(urlName), + System.Web.HttpUtility.UrlEncode(title)), "公示牌二维码", 340, 400)); } } #endregion diff --git a/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrol.aspx b/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrol.aspx index f2731cd..e80f95c 100644 --- a/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrol.aspx +++ b/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrol.aspx @@ -20,12 +20,12 @@ ShowHeader="false" Layout="VBox" BoxConfigAlign="Stretch"> + OnRowCommand="Grid1_RowCommand" EnableTextSelection="True" EnableCheckBoxSelect="true" KeepCurrentSelection="true"> @@ -46,6 +46,9 @@ + + @@ -58,22 +61,18 @@ - + + - - - - @@ -81,8 +80,19 @@ ForeColor='<%# GetPatrolStatusColor(Eval("PatrolStatus")) %>' Font-Bold="true"> + + + + + HeaderText="巡检附件" HeaderTextAlign="Center" TextAlign="Center" Text="查看"> + + diff --git a/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrol.aspx.cs b/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrol.aspx.cs index dc31356..b3b2137 100644 --- a/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrol.aspx.cs +++ b/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrol.aspx.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Drawing; +using System.IO; +using System.IO.Compression; using System.Linq; namespace FineUIPro.Web.HSSE.HazardousMG @@ -35,6 +37,117 @@ namespace FineUIPro.Web.HSSE.HazardousMG } } + /// + /// 导出Word:每条记录生成独立文档(文档名使用监督巡视部位)。 + /// 单条直接下载 .docx;多条打包为 .zip,压缩包内每个 .docx 以监督巡视部位命名。 + /// + protected void btnOut_Click(object sender, EventArgs e) + { + string[] ids = Grid1.SelectedRowIDArray; + if (ids == null || ids.Length == 0) + { + Alert.ShowInTop("请先勾选要导出的巡检记录!", MessageBoxIcon.Warning); + return; + } + + List> files = new List>(); + int dupIndex = 0; + foreach (string id in ids) + { + if (string.IsNullOrEmpty(id)) + { + continue; + } + Model.HSSE_SafetyPatrol info = BLL.SafetyPatrolService.GetById(id); + if (info == null) + { + continue; + } + byte[] bytes = BLL.SafetyPatrolWordService.Generate(id); + if (bytes == null) + { + continue; + } + ////文件名 = 监督巡视部位 + 编号(编码唯一,规避同名覆盖) + string baseName = SanitizeFileName(info.HazardProjectName); + string codeSuffix = string.IsNullOrEmpty(info.Code) ? string.Empty : "_" + info.Code; + string fileName = baseName + codeSuffix + ".docx"; + // 同名记录去重,避免覆盖 + while (files.Any(f => f.Key == fileName)) + { + dupIndex++; + fileName = baseName + "(" + dupIndex + ").docx"; + } + files.Add(new KeyValuePair(fileName, bytes)); + } + + if (files.Count == 0) + { + Alert.ShowInTop("未找到有效巡检记录!", MessageBoxIcon.Warning); + return; + } + + Response.Clear(); + if (files.Count == 1) + { + // 单条:直接下发 .docx + Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; + Response.AddHeader("Content-Disposition", "attachment; filename=" + System.Web.HttpUtility.UrlEncode(files[0].Key, System.Text.Encoding.UTF8)); + Response.BinaryWrite(files[0].Value); + } + else + { + // 多条:打包为 .zip + Response.ContentType = "application/zip"; + Response.AddHeader("Content-Disposition", "attachment; filename=" + System.Web.HttpUtility.UrlEncode("安全巡检记录_" + BLL.Funs.GetNewFileName() + ".zip", System.Text.Encoding.UTF8)); + using (MemoryStream ms = new MemoryStream()) + { + using (ZipArchive zip = new ZipArchive(ms, ZipArchiveMode.Create, true)) + { + foreach (KeyValuePair f in files) + { + ZipArchiveEntry entry = zip.CreateEntry(f.Key, CompressionLevel.Optimal); + using (Stream es = entry.Open()) + { + es.Write(f.Value, 0, f.Value.Length); + } + } + } + Response.BinaryWrite(ms.ToArray()); + } + } + Response.Flush(); + Response.End(); + } + + /// + /// 清洗文件名(去非法字符),保证文件名合法可下载。 + /// + /// 监督巡视部位名称 + /// 合法文件名(不含扩展名) + private static string SanitizeFileName(string name) + { + if (string.IsNullOrEmpty(name)) + { + return "监督记录表"; + } + string fileName = name; + foreach (char c in Path.GetInvalidFileNameChars()) + { + fileName = fileName.Replace(c, '_'); + } + fileName = fileName.Trim(); + if (fileName.Length == 0) + { + return "监督记录表"; + } + if (fileName.Length > 80) + { + fileName = fileName.Substring(0, 80); + } + return fileName; + } + /// /// 扫码巡检按钮事件 /// @@ -51,12 +164,20 @@ namespace FineUIPro.Web.HSSE.HazardousMG #region 模板绑定辅助方法 /// - /// 巡检状态颜色(待整改标红) + /// 巡检状态颜色(待整改标红、整改待复查标橙、正常标绿) /// public Color GetPatrolStatusColor(object value) { string state = value == null ? "" : value.ToString(); - return state == "待整改" ? Color.Red : Color.Green; + switch (state) + { + case "待整改": + return Color.Red; + case "整改待复查": + return Color.Orange; + default: + return Color.Green; + } } #endregion @@ -217,6 +338,11 @@ namespace FineUIPro.Web.HSSE.HazardousMG PageContext.RegisterStartupScript(WindowAtt.GetShowReference(String.Format("../../AttachFile/webuploader.aspx?type={0}&toKeyId={1}&path=FileUpload/SafetyPatrol&menuId={2}", -1, e.RowID, BLL.Const.SafetyPatrolMenuId))); } + else if (e.CommandName == "attchUrlRectify") + { + PageContext.RegisterStartupScript(WindowAtt.GetShowReference(String.Format("../../AttachFile/webuploader.aspx?type={0}&toKeyId={1}&path=FileUpload/SafetyPatrolCorrect&menuId={2}", + -1, e.RowID, BLL.Const.SafetyPatrolRectifyMenuId))); + } } #endregion } diff --git a/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrolEdit.aspx b/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrolEdit.aspx index 8ebd705..bf435a1 100644 --- a/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrolEdit.aspx +++ b/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrolEdit.aspx @@ -7,70 +7,160 @@ 编辑安全巡检记录 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + 附件9 (危大工程类别)监督记录表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 监督巡视内容 + 发现问题 + + + + 1、施工条件保持情况 + 2、按方案施工情况,实体与方案参数的对比 + 3、现场安全防护状况 + 4、作业人员持证上岗情况 + 其它: + + + + + + + 处理要求: + 签收人: + + + + + + + + 整改后复查情况: + + + + + + + + 备注: + + + + + + + + 监督巡视人员: + + + + + + + + + + diff --git a/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrolEdit.aspx.cs b/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrolEdit.aspx.cs index c489aa9..105c4ec 100644 --- a/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrolEdit.aspx.cs +++ b/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrolEdit.aspx.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.RegularExpressions; namespace FineUIPro.Web.HSSE.HazardousMG { @@ -24,6 +25,21 @@ namespace FineUIPro.Web.HSSE.HazardousMG ViewState["PatrolId"] = value; } } + + /// + /// 巡检状态(编辑页已不提供选择,加载时保留原值,新增默认正常) + /// + private string PatrolStatus + { + get + { + return (string)ViewState["PatrolStatus"]; + } + set + { + ViewState["PatrolStatus"] = value; + } + } #endregion #region 加载 @@ -36,11 +52,6 @@ namespace FineUIPro.Web.HSSE.HazardousMG { this.btnClose.OnClientClick = ActiveWindow.GetHideReference(); this.InitDropDownList(); - ////巡检人关联当前登录账号 - if (this.CurrUser != null) - { - this.lblPatrolMan.Text = this.CurrUser.UserName; - } this.PatrolId = Request.Params["PatrolId"]; if (!string.IsNullOrEmpty(this.PatrolId)) { @@ -56,19 +67,26 @@ namespace FineUIPro.Web.HSSE.HazardousMG { this.dpPatrolDate.SelectedDate = info.PatrolDate.Value; } - if (!string.IsNullOrEmpty(info.PatrolStatus)) - { - this.ddlPatrolStatus.SelectedValue = info.PatrolStatus; - } - this.txtContent.Text = info.Content; + this.txtCode.Text = info.Code; + this.PatrolStatus = string.IsNullOrEmpty(info.PatrolStatus) ? "正常" : info.PatrolStatus; + this.InitUserDropDownList(info.PatrolMan, info.PatrolManId, info.Receiver, info.ReceiverId); + this.RenderContent(info.Content); + this.txtProblems.Text = info.Problems; + this.txtHandleRequire.Text = info.HandleRequire; + this.txtRectifyReview.Text = info.RectifyReview; + this.txtRemarks.Text = info.Remarks; } } else { - ////新增(扫码巡检):默认巡检日期为当天、巡检状态为正常 + ////新增(扫码巡检):默认巡检日期为当天、巡检状态为正常;巡检人默认当前登录账号 this.dpPatrolDate.SelectedDate = DateTime.Now; - this.ddlPatrolStatus.SelectedValue = "正常"; + this.PatrolStatus = "正常"; + this.InitUserDropDownList(null, null, null, null); } + ////让父级编辑窗口高度自适应内容,避免固定高度留下大空白;超过 720px 时内部滚动 + string fitJs = "setTimeout(function(){try{var w=F.activeWindow;if(w){var el=document.getElementById('patrolContent');var h=el?el.offsetHeight:0;h+=40;if(h>720){h=720;}w.setSize(780,h);}}catch(e){}},200);"; + PageContext.RegisterStartupScript(fitJs); } } @@ -87,6 +105,123 @@ namespace FineUIPro.Web.HSSE.HazardousMG this.ddlHazardProject.Items.Add(new FineUIPro.ListItem(p.ProjectName + "(" + p.ProjectCode + ")", p.HazardProjectId)); } } + + /// + /// 绑定巡检人、签收人下拉(来自项目用户) + /// + /// 巡检人名称(回显用) + /// 巡检人ID(回显用) + /// 签收人名称(回显用) + /// 签收人ID(回显用) + private void InitUserDropDownList(string patrolMan, string patrolManId, string receiver, string receiverId) + { + if (this.CurrUser == null || string.IsNullOrEmpty(this.CurrUser.LoginProjectId)) + { + return; + } + List users = BLL.UserService.GetProjectUserListByProjectId(this.CurrUser.LoginProjectId); + ////巡检人(默认当前登录账号);签收人允许留空 + this.BindPatrolUser(this.ddlPatrolMan, users, patrolMan, patrolManId, this.CurrUser.UserId); + this.BindPatrolUser(this.ddlReceiver, users, receiver, receiverId, null); + } + + /// + /// 绑定单个用户下拉:优先按ID回显,其次按名称回显;均不匹配且名称有值时保留原名称 + /// + /// 目标下拉 + /// 项目用户列表 + /// 回显名称 + /// 回显ID + /// 默认选中用户ID(可空) + private void BindPatrolUser(FineUIPro.DropDownList ddl, List users, string selectName, string selectId, string defaultUserId) + { + ddl.Items.Clear(); + ////签收人允许留空(首项为占位) + if (ddl.ID == "ddlReceiver") + { + ddl.Items.Add(new FineUIPro.ListItem("请选择", "")); + } + string selectValue = string.IsNullOrEmpty(selectId) ? string.Empty : selectId; + foreach (Model.Sys_User u in users) + { + ////默认选中项(巡检人默认当前登录账号) + if (string.IsNullOrEmpty(selectValue) && !string.IsNullOrEmpty(defaultUserId) && u.UserId == defaultUserId) + { + selectValue = u.UserId; + } + ////名称回显(老数据无ID) + if (string.IsNullOrEmpty(selectValue) && !string.IsNullOrEmpty(selectName) && u.UserName == selectName) + { + selectValue = u.UserId; + } + ddl.Items.Add(new FineUIPro.ListItem(u.UserName, u.UserId)); + } + ////名称在项目用户中找不到(如外部人员):追加原名称选项,保留旧数据 + if (string.IsNullOrEmpty(selectValue) && !string.IsNullOrEmpty(selectName)) + { + ddl.Items.Insert(0, new FineUIPro.ListItem(selectName, "")); + } + if (!string.IsNullOrEmpty(selectValue)) + { + ddl.SelectedValue = selectValue; + } + else if (ddl.Items.Count > 0) + { + ddl.SelectedIndex = 0; + } + } + + /// + /// 根据巡视内容渲染"其它"输入框。1-4 项为固定默认值(写死、始终显示),不再从 Content 解析勾选。 + /// Content 以后只存「其它」内容:兼容旧格式「…;其它:xxx」,也兼容直接为其它文本的新格式。 + /// + /// Content 字段(以后仅其它内容;旧数据可能形如:1、…;4、…;其它:xxx) + private void RenderContent(string content) + { + if (string.IsNullOrEmpty(content)) + { + return; + } + string other = null; + foreach (string seg in content.Split(';')) + { + string s = seg.Trim(); + if (s.Length == 0) + { + continue; + } + if (s.StartsWith("其它") || s.StartsWith("其他")) + { + int idx = s.IndexOf(':'); + other = idx >= 0 ? s.Substring(idx + 1).Trim() : string.Empty; + break; + } + } + // 新格式:Content 无「其它:」前缀、且不以项号前缀(1、…)开头,则整段即为其它内容 + if (other == null) + { + other = Regex.IsMatch(content, @"^\s*\d+、") ? string.Empty : content.Trim(); + } + if (other.Length > 0) + { + this.txtContentOther.Text = other; + } + } + + /// + /// 构造 Content 文本。1-4 项固定写死(始终显示,不参与存储),Content 仅存「其它」内容。 + /// 「其它」无多选:输入框有内容即表示选中。 + /// + /// 如:其它:基坑围挡损坏;无其它内容返回空串 + private string BuildContent() + { + string other = this.txtContentOther.Text.Trim(); + if (other.Length > 0) + { + return "其它:" + other; + } + return string.Empty; + } #endregion #region 保存 @@ -100,16 +235,14 @@ namespace FineUIPro.Web.HSSE.HazardousMG Alert.ShowInTop("请先选择项目!", MessageBoxIcon.Warning); return; } - ////新增时先生成主键,保证附件能挂到同一记录 + ////新增时先生成主键 if (string.IsNullOrEmpty(this.PatrolId)) { this.PatrolId = Guid.NewGuid().ToString(); } - ////校验附件是否已上传 - Model.AttachFile attach = BLL.Funs.DB.AttachFile.FirstOrDefault(x => x.ToKeyId == this.PatrolId); - if (attach == null || string.IsNullOrEmpty(attach.AttachUrl)) + if (string.IsNullOrEmpty(this.ddlHazardProject.SelectedValue)) { - Alert.ShowInTop("请上传巡检图片!", MessageBoxIcon.Warning); + Alert.ShowInTop("请选择危大工程类别!", MessageBoxIcon.Warning); return; } ////根据所选清单回填工程名称 @@ -119,6 +252,19 @@ namespace FineUIPro.Web.HSSE.HazardousMG { hazardProjectName = project.ProjectName; } + ////巡检人、签收人(下拉选中项:ID + 名称;外部人员无ID时仅保留名称) + string patrolManId = this.ddlPatrolMan.SelectedValue; + string patrolManName = this.ddlPatrolMan.SelectedItem == null ? string.Empty : this.ddlPatrolMan.SelectedItem.Text.Trim(); + if (patrolManName == "请选择") + { + patrolManName = string.Empty; + } + string receiverId = this.ddlReceiver.SelectedValue; + string receiverName = this.ddlReceiver.SelectedItem == null ? string.Empty : this.ddlReceiver.SelectedItem.Text.Trim(); + if (receiverName == "请选择") + { + receiverName = string.Empty; + } Model.HSSE_SafetyPatrol info = new Model.HSSE_SafetyPatrol { PatrolId = this.PatrolId, @@ -126,9 +272,16 @@ namespace FineUIPro.Web.HSSE.HazardousMG HazardProjectId = this.ddlHazardProject.SelectedValue, HazardProjectName = hazardProjectName, PatrolDate = this.dpPatrolDate.SelectedDate, - PatrolMan = this.CurrUser.UserName, - PatrolStatus = this.ddlPatrolStatus.SelectedValue, - Content = this.txtContent.Text.Trim() + PatrolMan = patrolManName, + PatrolManId = patrolManId, + PatrolStatus = this.PatrolStatus, + Content = this.BuildContent(), + Problems = this.txtProblems.Text.Trim(), + Receiver = receiverName, + ReceiverId = receiverId, + HandleRequire = this.txtHandleRequire.Text.Trim(), + RectifyReview = this.txtRectifyReview.Text.Trim(), + Remarks = this.txtRemarks.Text.Trim() }; ////存在则更新,不存在则新增(服务层已处理) BLL.SafetyPatrolService.Update(info); @@ -146,6 +299,18 @@ namespace FineUIPro.Web.HSSE.HazardousMG } PageContext.RegisterStartupScript(WindowAtt.GetShowReference(String.Format("~/AttachFile/webuploader.aspx?type=0&toKeyId={0}&path=FileUpload/SafetyPatrol&menuId={1}", this.PatrolId, BLL.Const.SafetyPatrolMenuId))); } + + /// + /// 上传整改图片 + /// + protected void btnAttachRectify_Click(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(this.PatrolId)) + { + this.PatrolId = Guid.NewGuid().ToString(); + } + PageContext.RegisterStartupScript(WindowAtt.GetShowReference(String.Format("~/AttachFile/webuploader.aspx?type=0&toKeyId={0}&path=FileUpload/SafetyPatrolCorrect&menuId={1}", this.PatrolId, BLL.Const.SafetyPatrolRectifyMenuId))); + } #endregion } } diff --git a/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrolEdit.aspx.designer.cs b/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrolEdit.aspx.designer.cs index c43744c..d7288a4 100644 --- a/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrolEdit.aspx.designer.cs +++ b/SGGL/FineUIPro.Web/HSSE/HazardousMG/SafetyPatrolEdit.aspx.designer.cs @@ -33,13 +33,22 @@ namespace FineUIPro.Web.HSSE.HazardousMG protected global::FineUIPro.PageManager PageManager1; /// - /// SimpleForm1 控件。 + /// ContentPanel1 控件。 /// /// /// 自动生成的字段。 /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 /// - protected global::FineUIPro.Form SimpleForm1; + protected global::FineUIPro.ContentPanel ContentPanel1; + + /// + /// FormHazard 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.Form FormHazard; /// /// ddlHazardProject 控件。 @@ -50,6 +59,15 @@ namespace FineUIPro.Web.HSSE.HazardousMG /// protected global::FineUIPro.DropDownList ddlHazardProject; + /// + /// FormDate 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.Form FormDate; + /// /// dpPatrolDate 控件。 /// @@ -60,49 +78,76 @@ namespace FineUIPro.Web.HSSE.HazardousMG protected global::FineUIPro.DatePicker dpPatrolDate; /// - /// ddlPatrolStatus 控件。 + /// txtContentOther 控件。 /// /// /// 自动生成的字段。 /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 /// - protected global::FineUIPro.DropDownList ddlPatrolStatus; + protected global::FineUIPro.TextBox txtContentOther; /// - /// lblPatrolMan 控件。 + /// txtCode 控件。 /// /// /// 自动生成的字段。 /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 /// - protected global::FineUIPro.Label lblPatrolMan; + protected global::FineUIPro.TextBox txtCode; /// - /// txtContent 控件。 + /// txtProblems 控件。 /// /// /// 自动生成的字段。 /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 /// - protected global::FineUIPro.TextArea txtContent; + protected global::FineUIPro.TextArea txtProblems; /// - /// Panel2 控件。 + /// ddlReceiver 控件。 /// /// /// 自动生成的字段。 /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 /// - protected global::FineUIPro.Panel Panel2; + protected global::FineUIPro.DropDownList ddlReceiver; /// - /// Label1 控件。 + /// txtHandleRequire 控件。 /// /// /// 自动生成的字段。 /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 /// - protected global::FineUIPro.Label Label1; + protected global::FineUIPro.TextArea txtHandleRequire; + + /// + /// txtRectifyReview 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.TextArea txtRectifyReview; + + /// + /// txtRemarks 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.TextArea txtRemarks; + + /// + /// ddlPatrolMan 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.DropDownList ddlPatrolMan; /// /// btnAttach 控件。 @@ -114,22 +159,13 @@ namespace FineUIPro.Web.HSSE.HazardousMG protected global::FineUIPro.Button btnAttach; /// - /// Toolbar1 控件。 + /// btnAttachRectify 控件。 /// /// /// 自动生成的字段。 /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 /// - protected global::FineUIPro.Toolbar Toolbar1; - - /// - /// ToolbarFill1 控件。 - /// - /// - /// 自动生成的字段。 - /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 - /// - protected global::FineUIPro.ToolbarFill ToolbarFill1; + protected global::FineUIPro.Button btnAttachRectify; /// /// btnSave 控件。 diff --git a/SGGL/FineUIPro.Web/common/Menu_CQMS.xml b/SGGL/FineUIPro.Web/common/Menu_CQMS.xml index 157a908..9f392fc 100644 --- a/SGGL/FineUIPro.Web/common/Menu_CQMS.xml +++ b/SGGL/FineUIPro.Web/common/Menu_CQMS.xml @@ -13,7 +13,6 @@ - diff --git a/SGGL/FineUIPro.Web/common/main3.aspx.cs b/SGGL/FineUIPro.Web/common/main3.aspx.cs index dc6a6fd..dec3714 100644 --- a/SGGL/FineUIPro.Web/common/main3.aspx.cs +++ b/SGGL/FineUIPro.Web/common/main3.aspx.cs @@ -146,7 +146,7 @@ namespace FineUIPro.Web.common // 检查列表 var query = ( from hsse in Funs.DB.HSSE_Hazard_HazardRegister - where hsse.RectifyName != null && hsse.RegisterDate > startd && hsse.RegisterDate < endd + where hsse.RectifyName != null && hsse.States != "4" && hsse.RegisterDate > startd && hsse.RegisterDate < endd group hsse by hsse.RectifyName into g1 select new { type = g1.Key, count = g1.Count() } diff --git a/SGGL/FineUIPro.Web/common/mainProject.aspx.cs b/SGGL/FineUIPro.Web/common/mainProject.aspx.cs index 9c4a6ed..7007c15 100644 --- a/SGGL/FineUIPro.Web/common/mainProject.aspx.cs +++ b/SGGL/FineUIPro.Web/common/mainProject.aspx.cs @@ -129,7 +129,7 @@ namespace FineUIPro.Web.common // 检查列表 var query = (from hsse in Funs.DB.HSSE_Hazard_HazardRegister - where hsse.RectifyName != null && hsse.ProjectId == ProjectId && hsse.RegisterDate> startd && hsse.RegisterDate < endd + where hsse.RectifyName != null && hsse.States != "4" && hsse.ProjectId == ProjectId && hsse.RegisterDate> startd && hsse.RegisterDate < endd group hsse by hsse.RectifyName into g1 select new { type = g1.Key, count = g1.Count() }).Union((from i in Funs.DB.Inspect_Inspection join itm in Funs.DB.Inspect_InspectionItem on i.InspectionId equals itm.InspectionId diff --git a/SGGL/Model/APIItem/HSSE/SafetyPatrolItem.cs b/SGGL/Model/APIItem/HSSE/SafetyPatrolItem.cs index dd6404a..8a44332 100644 --- a/SGGL/Model/APIItem/HSSE/SafetyPatrolItem.cs +++ b/SGGL/Model/APIItem/HSSE/SafetyPatrolItem.cs @@ -16,6 +16,15 @@ namespace Model set; } + /// + /// 编码(全局唯一,格式 XJ-序号,自动生成) + /// + public string Code + { + get; + set; + } + /// /// 项目ID /// @@ -53,7 +62,7 @@ namespace Model } /// - /// 巡检人 + /// 巡检人名称 /// public string PatrolMan { @@ -62,7 +71,16 @@ namespace Model } /// - /// 巡检状态(正常/待整改) + /// 巡检人ID + /// + public string PatrolManId + { + get; + set; + } + + /// + /// 巡检状态(正常/待整改/整改待复查) /// public string PatrolStatus { @@ -71,7 +89,7 @@ namespace Model } /// - /// 巡检内容 + /// 巡视内容(勾选项合并后的文本) /// public string Content { @@ -80,12 +98,75 @@ namespace Model } /// - /// 附件URL(逗号分隔) + /// 发现问题 + /// + public string Problems + { + get; + set; + } + + /// + /// 签收人名称 + /// + public string Receiver + { + get; + set; + } + + /// + /// 签收人ID + /// + public string ReceiverId + { + get; + set; + } + + /// + /// 处理要求 + /// + public string HandleRequire + { + get; + set; + } + + /// + /// 整改后复查情况 + /// + public string RectifyReview + { + get; + set; + } + + /// + /// 备注 + /// + public string Remarks + { + get; + set; + } + + /// + /// 附件URL(逗号分隔,巡视图片) /// public string AttachUrl { get; set; } + + /// + /// 整改图片URL(逗号分隔) + /// + public string RectifyAttachUrl + { + get; + set; + } } } diff --git a/SGGL/Model/HSSE_SafetyPatrol.Code.cs b/SGGL/Model/HSSE_SafetyPatrol.Code.cs new file mode 100644 index 0000000..0ff640c --- /dev/null +++ b/SGGL/Model/HSSE_SafetyPatrol.Code.cs @@ -0,0 +1,18 @@ +using System; +using System.Data.Linq.Mapping; + +namespace Model +{ + /// + /// 【补充部分类】为 HSSE_SafetyPatrol 提供编码(Code) 列映射。 + /// 说明:该列已由数据库脚本新增(见 DataBase/版本日志/SGGLDB_V2026-08-26-001-zones.sql), + /// 但本地无 SqlMetal,未通过 CreateModel.bat 重新生成 Model.cs,故以 partial 类补齐。 + /// 注意:若以后用 CreateModel.bat 重新生成 Model.cs,SqlMetal 会把 Code 一并生成, + /// 届时请删除本文件,避免出现重复的 Code 成员导致编译错误。 + /// + public partial class HSSE_SafetyPatrol + { + [Column(Name = "Code", DbType = "NVarChar(50)")] + public string Code { get; set; } + } +} diff --git a/SGGL/Model/Model.cs b/SGGL/Model/Model.cs index b5ee732..9e33287 100644 --- a/SGGL/Model/Model.cs +++ b/SGGL/Model/Model.cs @@ -220506,10 +220506,24 @@ namespace Model private string _PatrolMan; + private string _PatrolManId; + private string _PatrolStatus; private string _Content; + private string _Problems; + + private string _Receiver; + + private string _ReceiverId; + + private string _HandleRequire; + + private string _RectifyReview; + + private string _Remarks; + #region 可扩展性方法定义 partial void OnLoaded(); partial void OnValidate(System.Data.Linq.ChangeAction action); @@ -220526,10 +220540,24 @@ namespace Model partial void OnPatrolDateChanged(); partial void OnPatrolManChanging(string value); partial void OnPatrolManChanged(); + partial void OnPatrolManIdChanging(string value); + partial void OnPatrolManIdChanged(); partial void OnPatrolStatusChanging(string value); partial void OnPatrolStatusChanged(); partial void OnContentChanging(string value); partial void OnContentChanged(); + partial void OnProblemsChanging(string value); + partial void OnProblemsChanged(); + partial void OnReceiverChanging(string value); + partial void OnReceiverChanged(); + partial void OnReceiverIdChanging(string value); + partial void OnReceiverIdChanged(); + partial void OnHandleRequireChanging(string value); + partial void OnHandleRequireChanged(); + partial void OnRectifyReviewChanging(string value); + partial void OnRectifyReviewChanged(); + partial void OnRemarksChanging(string value); + partial void OnRemarksChanged(); #endregion public HSSE_SafetyPatrol() @@ -220657,6 +220685,26 @@ namespace Model } } + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_PatrolManId", DbType="NVarChar(50)")] + public string PatrolManId + { + get + { + return this._PatrolManId; + } + set + { + if ((this._PatrolManId != value)) + { + this.OnPatrolManIdChanging(value); + this.SendPropertyChanging(); + this._PatrolManId = value; + this.SendPropertyChanged("PatrolManId"); + this.OnPatrolManIdChanged(); + } + } + } + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_PatrolStatus", DbType="NVarChar(50)")] public string PatrolStatus { @@ -220697,6 +220745,126 @@ namespace Model } } + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Problems", DbType="NVarChar(1000)")] + public string Problems + { + get + { + return this._Problems; + } + set + { + if ((this._Problems != value)) + { + this.OnProblemsChanging(value); + this.SendPropertyChanging(); + this._Problems = value; + this.SendPropertyChanged("Problems"); + this.OnProblemsChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Receiver", DbType="NVarChar(50)")] + public string Receiver + { + get + { + return this._Receiver; + } + set + { + if ((this._Receiver != value)) + { + this.OnReceiverChanging(value); + this.SendPropertyChanging(); + this._Receiver = value; + this.SendPropertyChanged("Receiver"); + this.OnReceiverChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ReceiverId", DbType="NVarChar(50)")] + public string ReceiverId + { + get + { + return this._ReceiverId; + } + set + { + if ((this._ReceiverId != value)) + { + this.OnReceiverIdChanging(value); + this.SendPropertyChanging(); + this._ReceiverId = value; + this.SendPropertyChanged("ReceiverId"); + this.OnReceiverIdChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_HandleRequire", DbType="NVarChar(1000)")] + public string HandleRequire + { + get + { + return this._HandleRequire; + } + set + { + if ((this._HandleRequire != value)) + { + this.OnHandleRequireChanging(value); + this.SendPropertyChanging(); + this._HandleRequire = value; + this.SendPropertyChanged("HandleRequire"); + this.OnHandleRequireChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RectifyReview", DbType="NVarChar(1000)")] + public string RectifyReview + { + get + { + return this._RectifyReview; + } + set + { + if ((this._RectifyReview != value)) + { + this.OnRectifyReviewChanging(value); + this.SendPropertyChanging(); + this._RectifyReview = value; + this.SendPropertyChanged("RectifyReview"); + this.OnRectifyReviewChanged(); + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Remarks", DbType="NVarChar(500)")] + public string Remarks + { + get + { + return this._Remarks; + } + set + { + if ((this._Remarks != value)) + { + this.OnRemarksChanging(value); + this.SendPropertyChanging(); + this._Remarks = value; + this.SendPropertyChanged("Remarks"); + this.OnRemarksChanged(); + } + } + } + public event PropertyChangingEventHandler PropertyChanging; public event PropertyChangedEventHandler PropertyChanged; diff --git a/SGGL/Model/Model.csproj b/SGGL/Model/Model.csproj index 249cd9f..f805492 100644 --- a/SGGL/Model/Model.csproj +++ b/SGGL/Model/Model.csproj @@ -247,6 +247,7 @@ + diff --git a/SGGL/WebAPI/Controllers/HSSE/HazardousMG/SafetyPatrolController.cs b/SGGL/WebAPI/Controllers/HSSE/HazardousMG/SafetyPatrolController.cs index 1f9b41b..01ac2e1 100644 --- a/SGGL/WebAPI/Controllers/HSSE/HazardousMG/SafetyPatrolController.cs +++ b/SGGL/WebAPI/Controllers/HSSE/HazardousMG/SafetyPatrolController.cs @@ -34,6 +34,7 @@ namespace WebAPI.Controllers.HSSE.HazardousMG foreach (var item in dataList) { item.AttachUrl = AttachFileService.getFileUrl(item.PatrolId, Const.SafetyPatrolMenuId); + item.RectifyAttachUrl = AttachFileService.getFileUrl(item.PatrolId, Const.SafetyPatrolRectifyMenuId); } responeData.data = new { totalCount, dataList }; } @@ -62,6 +63,7 @@ namespace WebAPI.Controllers.HSSE.HazardousMG { ////附件关联 item.AttachUrl = AttachFileService.getFileUrl(item.PatrolId, Const.SafetyPatrolMenuId); + item.RectifyAttachUrl = AttachFileService.getFileUrl(item.PatrolId, Const.SafetyPatrolRectifyMenuId); } responeData.data = item; } diff --git a/SGGL/WebAPI/SafetyPatrol_API.md b/SGGL/WebAPI/SafetyPatrol_API.md deleted file mode 100644 index 364265f..0000000 --- a/SGGL/WebAPI/SafetyPatrol_API.md +++ /dev/null @@ -1,168 +0,0 @@ -# 安全巡检接口文档 - -## 1. 概述 - -- **基础地址**:`http://{host}:{port}`(WebAPI 独立站点,本地调试默认 `http://localhost:7143`) -- **路由规则**:`api/{controller}/{action}/{id}` -- **Controller**:`SafetyPatrol` -- **数据格式**:JSON(请求体、响应体均为 JSON) - -## 2. 通用返回结构 `ResponeData` - -所有接口统一返回以下结构: - -| 字段 | 类型 | 说明 | -|------|------|------| -| `code` | int | `1` 成功,`0` 失败 | -| `message` | string | 提示消息(成功时为空,失败时为异常信息) | -| `data` | object | 业务数据(各接口不同,见下文) | - -```json -{ - "code": 1, - "message": null, - "data": { } -} -``` - -## 3. 数据对象 `SafetyPatrolItem` - -| 字段 | 类型 | 必填 | 说明 | -|------|------|------|------| -| `PatrolId` | string | 编辑时必填 | 主键(新增时可不传,服务端自动生成 GUID) | -| `ProjectId` | string | 新增时必填 | 项目主键 | -| `HazardProjectId` | string | 否 | 危大、超危工程主键 | -| `HazardProjectName` | string | 否 | 工程名称 | -| `PatrolDate` | datetime | 否 | 巡检日期(ISO 格式,如 `2026-08-19T10:00:00`) | -| `PatrolMan` | string | 否 | 巡检人 | -| `PatrolStatus` | string | 否 | 巡检状态:`正常` / `待整改` | -| `Content` | string | 否 | 巡检内容(语音转文字) | -| `AttachUrl` | string | 否 | 巡检图片附件 URL(逗号分隔);查询接口自动回填,新增/编辑时传入则自动写入附件表关联 | - -## 4. 接口列表 - -### 4.1 获取安全巡检分页列表 - -- **请求方式**:`GET` -- **URL**:`/api/SafetyPatrol/getSafetyPatrolList` - -**请求参数(Query)** - -| 参数 | 类型 | 必填 | 说明 | -|------|------|------|------| -| `projectId` | string | 是 | 项目主键 | -| `pageNumber` | int | 否 | 页码,从 1 开始;为 0 时不限制 | -| `pageSize` | int | 否 | 每页条数;为 0 时不限制 | -| `keyword` | string | 否 | 工程名称关键字(模糊匹配) | - -**示例** - -``` -GET /api/SafetyPatrol/getSafetyPatrolList?projectId=xxx&pageNumber=1&pageSize=10&keyword=基坑 -``` - -**返回 `data`** - -```json -{ - "totalCount": 12, - "dataList": [ - { - "PatrolId": "9f1a...", - "ProjectId": "xxx", - "HazardProjectId": "hd-001", - "HazardProjectName": "深基坑土方开挖工程", - "PatrolDate": "2026-08-19T10:00:00", - "PatrolMan": "张建国", - "PatrolStatus": "正常", - "Content": "现场深基坑边坡稳定,无裂缝。", - "AttachUrl": "fileupload/safetypatrol/patrol_001.jpg,fileupload/safetypatrol/patrol_002.jpg" - } - ] -} -``` - -### 4.2 获取安全巡检详情 - -- **请求方式**:`GET` -- **URL**:`/api/SafetyPatrol/getSafetyPatrolById` - -**请求参数(Query)** - -| 参数 | 类型 | 必填 | 说明 | -|------|------|------|------| -| `patrolId` | string | 是 | 巡检记录主键 | - -**示例** - -``` -GET /api/SafetyPatrol/getSafetyPatrolById?patrolId=9f1a... -``` - -**返回 `data`**:单个 `SafetyPatrolItem` 对象(含 `AttachUrl`),不存在时为 `null`。 - -### 4.3 新增安全巡检 - -- **请求方式**:`POST` -- **URL**:`/api/SafetyPatrol/addSafetyPatrol` -- **Content-Type**:`application/json` - -**请求体(JSON)** - -```json -{ - "ProjectId": "xxx", - "HazardProjectId": "hd-001", - "HazardProjectName": "深基坑土方开挖工程", - "PatrolDate": "2026-08-19T10:00:00", - "PatrolMan": "张建国", - "PatrolStatus": "正常", - "Content": "现场深基坑边坡稳定,无裂缝。", - "AttachUrl": "fileupload/safetypatrol/patrol_001.jpg" -} -``` - -> 说明:`AttachUrl` 非必填;传入图片 URL(多个用英文逗号分隔)时,服务端会自动写入附件表(`ToKeyId`=PatrolId、`MenuId`=SafetyPatrolMenuId),之后查询接口即可回读。 - -**返回 `data`** - -```json -{ "patrolId": "9f1a..." } -``` - -> 校验:`ProjectId` 为空时返回 `code=0`,`message="项目主键不能为空!"`。 - -### 4.4 编辑安全巡检 - -- **请求方式**:`POST` -- **URL**:`/api/SafetyPatrol/updateSafetyPatrol` -- **Content-Type**:`application/json` - -**请求体(JSON)**(需携带 `PatrolId`) - -```json -{ - "PatrolId": "9f1a...", - "ProjectId": "xxx", - "HazardProjectId": "hd-001", - "HazardProjectName": "深基坑土方开挖工程", - "PatrolDate": "2026-08-19T10:00:00", - "PatrolMan": "张建国", - "PatrolStatus": "待整改", - "Content": "边坡局部有积水,需整改。", - "AttachUrl": "fileupload/safetypatrol/patrol_003.jpg" -} -``` - -> 说明:传入 `AttachUrl` 时会覆盖该记录的原有附件;不传则保留原附件不变。 - -**返回 `data`**:成功时无数据(`data` 为空)。 - -> 校验:`PatrolId` 为空返回 `"巡检主键不能为空!"`;记录不存在返回 `"未找到对应记录!"`。 - -## 5. 错误码 - -| `code` | 含义 | -|--------|------| -| `1` | 成功 | -| `0` | 失败(`message` 为具体原因,如参数校验失败、数据库异常) |