65.9K
CodeProject 正在变化。 阅读更多。
Home

健康与安全管理系统

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.95/5 (10投票s)

2011年12月8日

CPOL

6分钟阅读

viewsIcon

38804

健康与安全管理系统是一个应用程序,用于帮助组织更好地管理和缓解健康与安全统计数据和关键绩效指标 (KPI)。

引言

您的应用程序/扩展程序做什么?它解决了什么业务问题?

健康与安全管理系统是一个应用程序,用于帮助组织更好地管理和缓解健康与安全统计数据和关键绩效指标 (KPI)。该解决方案旨在为用户提供捕获和报告精细化健康与安全绩效指标的工具。

工作场所安全在许多组织中扮演着日益重要的角色。公司现在不仅要对内部利益相关者(如员工和股东)负责,还要对其他外部利益相关者(如客户、供应商和合作伙伴)负责。无论是用于内部企业健康与安全 KPI 衡量,还是仅为通用最佳实践,组织都在不断提高健康与安全的可视性。

此外,公司现在普遍要求合作伙伴承担健康与安全责任,通常是在建立合作关系之前。例如,大型能源行业公司要求他们合作的供应商必须拥有健全的健康与安全计划业务流程。这些合作关系通常包括合同义务,要求供应商提供定期的健康与安全报告;尤其是在客户工作现场执行工作时。

健康与安全管理系统旨在为组织提供捕获和报告关键健康与安全指标的手段。健康与安全管理系统的主要价值主张包括:

  • 精细化的健康与安全信息收集,例如:
    • 观察 - 捕获识别健康与安全威胁和机会的数据,
    • 未遂事故 - 发生但未造成伤害或时间损失的事件,以及
    • 伤害和时间损失事件 - 管理有关伤害和时间损失的详细信息。
  • 灵活且直观的用户可配置报告,包括:
    • 几项“固定”的内置报告,可选择打印或导出为各种格式,如 Excel 或 PDF。
    • 强大的 OLAP 分析,高度可定制。
    • 灵活的用户自定义查询,可选择保存、重新加载、打印或导出。
  • 高度可配置,易于为每个客户进行定制。
  • 可快速与现有组织系统集成;例如,遗留客户或人力资源 ERP 系统。
  • 可部署到桌面、Web 或云。

这个应用程序有多少屏幕和实体?

目前,健康与安全管理系统包含:

  • 19 个屏幕,提供标准数据录入界面,以及各种管理任务,如查找或参考表、报告和分析以及安全性,以及
  • 23 个实体(表)。

LightSwitch 为您的业务节省了资金吗?如何节省?

LightSwitch 以极快的速度提供了构建解决方案的手段。该解决方案的质量堪比一个企业级解决方案,而使用其他更常见的技术来创建它将花费更多的时间和精力。

快速上市至关重要,产品的质量同样重要。使用 LightSwitch,可以使用经过验证的软件开发最佳实践技术创建解决方案。使用 LightSwitch 时,解决方案的质量会自动得到保障。使用基于模板的任务可以轻松实现各种场景和需求。

如果您没有 LightSwitch,这个应用程序还会被构建出来吗?如果会,用什么构建?

在考虑使用何种技术之前,该解决方案的概念就已经摆在桌面上了。曾考虑使用一种或多种技术,包括:ASP.Net MVC、HTML5/JSON、SQL Server 和 WCF。

再次强调,正如前面提到的,LightSwitch 显著缩短了交付时间。使用相对传统的开发技术将在交付需求方面花费更多时间。

这个应用程序支持多少用户?

根据需要。没有已知限制表明该解决方案无法部署到大型企业。

使用 LightSwitch 构建此应用程序实际花了多长时间?

在撰写本文时,该解决方案仅花费了几天时间构建。据估计,实际总工作小时数为 18 小时。

此应用程序是否使用任何 LightSwitch 扩展?如果使用,是哪些?您自己编写过这些扩展吗?如果编写过,是否公开发布?在哪里?

健康与安全管理系统使用了一些扩展和自定义控件。这些包括:

该解决方案开发的一个关键成功因素是尽可能利用现有的扩展和工具。目标是尽快满足需求。使用现有工具提供了实现场景的机会,而无需“重新发明轮子”。

LightSwitch 如何让您的开发人员生活更好?与您考虑过的其他选项相比,构建速度是否更快?

LightSwitch 在使用 LightSwitch 开发此解决方案时,对开发人员的体验产生了显著影响。与使用其他考虑过的技术相比,投入的精力和时间要少得多。

链接、截图、视频

链接

截图

HealthAndSafety001.png

健康与安全管理主页

HealthAndSafety002.png

新观察录入

HealthAndSafety003.png

伤害和时间损失

HealthAndSafety004.png

报告示例

HealthAndSafety005.png

一些非常灵活的数据挖掘功能...


HealthAndSafety006.png
...带有可视化效果!

HealthAndSafety007.png

直观的用户自定义查询,可以保存和加载以供以后使用。

代码和技术

在编码和技术方面,这里有一些可以应用于您自己的 LightSwitch 项目的有用技巧...

图片和图标

为应用程序应用图片和图标为整体应用增添了一些用户体验的吸引力。用于为应用程序每个屏幕的标题添加图片的流程包括:

  1. 创建尺寸合适的 .png 图片作为屏幕标题图片。
  2. 打开解决方案资源管理器文件视图。
  3. 将图片添加为客户端项目 Resources 文件夹中的嵌入资源。
    HealthAndSafety008.png
  4. 向屏幕元素树添加一个图像控件。该元素是 SilverLight Image 控件,因此该元素将无边框...
    HealthAndSafety009.png
  5. 在客户端项目的 UserCode 文件夹中创建了一个名为 MyImageHelper 的类(在文件视图中打开解决方案资源管理器)。
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.IO;
    using System.Reflection;
    using System.Windows.Media.Imaging;
    
    namespace LightSwitchApplication
    {
        public class MyImageHelper
        {
            public static byte[] GetImageByName(string fileName)
            {
                Assembly currentAssembly = Assembly.GetExecutingAssembly();
                Stream stream = currentAssembly.GetManifestResourceStream("LightSwitchApplication.Resources." + fileName);
                return GetStreamAsByteArray(stream);
            }
    
            public static BitmapImage GetBitmapImageByName(string fileName)
            {
                Assembly currentAssembly = Assembly.GetExecutingAssembly();
                Stream stream = currentAssembly.GetManifestResourceStream("LightSwitchApplication.Resources." + fileName);
                return GetBitmapImage(GetStreamAsByteArray(stream));
            }
    
            private static byte[] GetStreamAsByteArray(System.IO.Stream stream)
            {
                if (stream != null)
                {
                    int streamLength = Convert.ToInt32(stream.Length);
                    byte[] fileData = new byte[streamLength];
                    stream.Read(fileData, 0, streamLength);
                    stream.Close();
                    return fileData;
                }
                else
                {
                    return null;
                }
            }
    
            private static BitmapImage GetBitmapImage(byte[] bytes)
            {
                // Create a BitmapImage from a byte[];
                using (MemoryStream ms = new MemoryStream(bytes))
                {
                    var bi = new BitmapImage();
                    bi.SetSource(ms);
                    return bi;
                }
            }
    
        }
    }
  6. 然后回到主页屏幕,实现代码以检索并在屏幕上使用该图像...

            partial void AllIncidents_InitializeDataWorkspace(List<IDataService> saveChangesTo)
            {
             
                IContentItemProxy logo = this.FindControl("HomeHeaderLogo");
                logo.ControlAvailable += new EventHandler<ControlAvailableEventArgs>(HomeHeaderLogo_ControlAvailable);
            }
    
            void HomeHeaderLogo_ControlAvailable(object sender, ControlAvailableEventArgs e)
            {
                // Set image source to PNG logo.
                var img = e.Control as Image;
                if (img != null)
                    img.Source = MyImageHelper.GetBitmapImageByName("HealthAndSafetyLogo.png");
            }
  7. ...在应用程序打开屏幕时应用图像...

    HealthAndSafety010.png

其他技术

在此解决方案中还应用了其他一些技术,包括:

  • 中间“虚拟”屏幕 - 观察、未遂事故和伤害事件实际上都是“事件”实体的一种类型。当单击主页列表中任何事件的超链接时,将应用逻辑,以便根据所选事件的类型,应用程序将打开相应的事件类型屏幕。
  • 一个用于添加或编辑的详细信息屏幕 - 使用一个屏幕同时用于添加和编辑实体。这是通过向屏幕添加参数来实现的,通常是一个代表实体 ID 的整数参数。屏幕上的逻辑将解释应用程序是为新记录还是现有记录打开屏幕。例如...

            partial void InjuryIncidentScreen_InitializeDataWorkspace(List<IDataService> saveChangesTo)
            {
              
                Incident incident;
                if (!this.IncidentID.HasValue)
                {
                    incident = new Incident();
    
                    IncidentType incidentType = (from it in DataWorkspace.ApplicationData.IncidentTypes
                                    where it.IncidentTypeName == "Injury"
                                    select it).FirstOrDefault();
    
                    incident.IncidentType = incidentType;
                    incident.HoursLost = 0;
    
                    this.IncidentProperty = incident;
    
                }
                else
                {
                    int incidentId = (int)this.IncidentID;
                    
                    incident = (from i in DataWorkspace.ApplicationData.Incidents
                                         where i.Id == incidentId
                                         select i).FirstOrDefault();
    
                    this.IncidentProperty = incident;
                }  
                
            }
    

希望大家都能发现这些内容有用且实用。干杯!

我们的 Facebook 主页 上发布此竞赛条目的链接,让人们知道他们应该评价此提交!别忘了 在 Twitter 上关注我们 获取竞赛更新!祝您好运!

© . All rights reserved.