IApp接口
框架封装了整个应该程序的启动过程,也实现了启动画面、系统更新、同步日期、全局异常等常规功能,简化了系统的开发,因此需要提供功能扩展接口,系统中把相关的扩展点都封装在此接口中。
接口定义如下:
/// <summary>/// 应用程序扩展接口/// <para>/// 框架封装了整个应该程序的启动过程,也实现了启动画面\系统更新\同步日期\全局异常等常规功能/// 简化了系统的开发,因此需要提供功能扩展接口,系统中把相关的扩展点都封装在此接口中。/// </para>/// </summary>public interface IApp{/// <summary>/// 读取应用程序配置/// <para>/// 定义应用程序在启动之初,如何读取系统配置信息,此函数是启动的第一步执行。/// </para>/// </summary>WinFormSetting GetSetting();/// <summary>/// 保存应用程序配置/// <para>/// 当系统配置信息发生变化时,如何保存系统配置信息。/// </para>/// </summary>/// <param name="setting">配置对象</param>void SaveSetting(WinFormSetting setting);/// <summary>/// 获取表格配置对象/// <para>/// 系统中对表格控件可以进行属性自定义,此函数返回表格配置信息操作类。/// </para>/// </summary>IGridSetting GetGridSetting();/// <summary>/// 获取登陆窗口/// <para>/// 定义系统登录窗口,如不需要登录,请返回null。/// </para>/// </summary>Form GetLoginForm();/// <summary>/// 获取主窗口/// <para>/// 定义系统主界面。不允许为null。/// </para>/// </summary>Form GetMainForm();/// <summary>/// 获取启动屏幕/// <para>/// 定义系统启动屏幕,必须遵守DevExpress组件启动屏幕规范。/// </para>/// </summary>Type GetSplashScreen();/// <summary>/// 获取等待窗体/// <para>/// 定义系统等待窗体,必须遵守DevExpress组件等待窗体规范。/// </para>/// </summary>Type GetWaitForm();/// <summary>/// 获取接口对象/// <para>/// 定义系统后台通讯接口操作对象。/// </para>/// </summary>/// <param name="setting">应用设置</param>WebApi GetApi(WinFormSetting setting);/// <summary>/// 用户登录/// <para>/// 定义用户登录过程。/// </para>/// </summary>/// <param name="account">账号</param>/// <param name="password">密码</param>/// <param name="captcha">验证码</param>/// <returns>成功返回True</returns>BoolMessage<SysUser> UserLogin(string account, string password, string captcha);/// <summary>/// 验证用户/// <para>/// 验证用户账号密码是否正确,与登录函数不同的是,此函数只验证账号密码,而用户登录还会有其他安全相关的操作和日志记录。/// </para>/// </summary>/// <param name="account">账号</param>/// <param name="password">密码</param>/// <param name="captcha">验证码</param>/// <returns>成功返回True</returns>BoolMessage UserValid(string account, string password, string captcha);/// <summary>/// 获取用户拥有的模块集合/// <para>/// 获取当前用户拥有的系统模块集合。/// </para>/// </summary>/// <param name="user">用户对象</param>IList<SysModule> GetModules(SysUser user);/// <summary>/// 客户端与服务端网络测试/// <para>/// 客户端和服务端进行网络测试。/// </para>/// </summary>bool Ping();/// <summary>/// 客户端心跳/// <para>/// 激活当前用户,保持当前客户端在线。/// </para>/// </summary>/// <param name="id">当前应用或者用户标识</param>bool Active(string id);/// <summary>/// 全局处理异常/// <para>/// 定义系统全局异常处理,只有用户未处理的异常才会再此统一处理,如果用户在函数中编写try catch,则不会触发此函数。/// </para>/// </summary>/// <param name="e">异常对象</param>void GlobalExceptionProcess(Exception e);}
默认实现
以下为系统默认实现,默认实现中所有的函数都是虚函数,每个函数都可以重写,根据自身的业务情况,重新相关函数。
namespace XCI.Sys{/// <summary>/// 系统默认应用程序接口/// <para>/// 默认实现了系统应用程序接口,所有函数都是虚函数,可根据业务情况,重新父类函数。/// </para>/// </summary>public class BaseApplication : IApp{/// <summary>/// 读取应用程序配置/// <para>/// 定义应用程序在启动之初,此函数是启动的第一步执行。/// 默认实现是从输出目录下的app.json文件中读取配置信息/// </para>/// </summary>public virtual WinFormSetting GetSetting(){return ConfigFactory.Default.Get("WinForm", () => new WinFormSetting());}/// <summary>/// 保存应用程序配置/// <para>/// 当系统配置信息发生变化时,把配置信息保存到输出目录下的app.json文件/// </para>/// </summary>/// <param name="setting">配置对象</param>public virtual void SaveSetting(WinFormSetting setting){ConfigFactory.Default.Save();}/// <summary>/// 获取表格配置对象/// <para>/// 系统中对表格控件可以进行属性自定义,此函数返回对象可以对用户保存的配置文件上传到服务器,也可以指定本地模式,不上传到服务器。/// </para>/// </summary>public virtual IGridSetting GetGridSetting(){//如果没有指定服务器地址,则使用本地模式return new DefaultGridSetting(SysRuntime.Setting.GridSettingLocalMode);}/// <summary>/// 获取登陆窗口/// <para>/// 定义系统登录窗口,如不需要登录,请返回null。/// </para>/// </summary>public virtual Form GetLoginForm(){return new FrmStandardLogin();}/// <summary>/// 获取主窗口/// <para>/// 定义系统主界面。不允许为null。/// </para>/// </summary>public virtual Form GetMainForm(){return new FrmStandardMain();}/// <summary>/// 获取启动屏幕/// <para>/// 定义系统启动屏幕,必须遵守DevExpress组件启动屏幕规范。/// </para>/// </summary>public virtual Type GetSplashScreen(){return typeof(FrmSplashScreen);}/// <summary>/// 获取等待窗体/// <para>/// 定义系统等待窗体,必须遵守DevExpress组件等待窗体规范。/// </para>/// </summary>public virtual Type GetWaitForm(){return typeof(FrmWait);}/// <summary>/// 获取接口对象/// <para>/// 定义系统后台通讯接口操作对象,函数返回值实现了在请求服务器时自动添加应用标识、时间戳、token等请求头。/// </para>/// </summary>/// <param name="setting">应用设置</param>public virtual WebApi GetApi(WinFormSetting setting){return new SysWebApi(setting.Id,setting.ApiUrl,TimeSpan.FromMilliseconds(setting.ApiTimeout),setting.IsDebugMode);}/// <summary>/// 用户登录/// <para>/// 定义用户登录过程。/// </para>/// </summary>/// <param name="account">账号</param>/// <param name="password">密码</param>/// <param name="captcha">验证码</param>/// <returns>成功返回True</returns>public virtual BoolMessage<SysUser> UserLogin(string account, string password, string captcha){return UserService.Instance.Login(account, password, captcha);}/// <summary>/// 验证用户/// <para>/// 验证用户账号密码是否正确,与登录函数不同的是,此函数只验证账号密码,而用户登录还会有其他安全相关的操作和日志记录。/// </para>/// </summary>/// <param name="account">账号</param>/// <param name="password">密码</param>/// <param name="captcha">验证码</param>/// <returns>成功返回True</returns>public virtual BoolMessage UserValid(string account, string password, string captcha){return UserService.Instance.ValidUser(account, password, captcha);}/// <summary>/// 获取用户拥有的模块集合/// <para>/// 获取当前用户拥有的系统模块集合。/// </para>/// </summary>/// <param name="user">用户对象</param>public virtual IList<SysModule> GetModules(SysUser user){return ModuleService.Instance.SelectListByUserId(user.Id);}/// <summary>/// 客户端与服务端网络测试/// <para>/// 客户端和服务端进行网络测试。/// </para>/// </summary>public virtual bool Ping(){return SysService.Instance.Ping();}/// <summary>/// 客户端心跳/// <para>/// 激活当前用户,保持当前客户端在线。/// </para>/// </summary>/// <param name="id">当前应用或者用户标识</param>public virtual bool Active(string id){return OnlineUserService.Instance.Active(id);}/// <summary>/// 全局处理异常/// <para>/// 定义系统全局异常处理,只有用户未处理的异常才会再此统一处理,如果用户在函数中编写try catch,则不会触发此函数。/// </para>/// </summary>/// <param name="e">异常对象</param>public virtual void GlobalExceptionProcess(Exception e){if (e is ControlValueException){return;}if (e is SocketException se){MessageBoxHelper.ShowError(DebugHelper.BuildAllMessage(se));}else if (e is AggregateException ae){ae.Handle(p => true);MessageBoxHelper.ShowError(DebugHelper.BuildAllMessage(ae.InnerExceptions.ToArray()));}else if (e is WebApiException || e is BoolMessageFailException || e is BoolMessageValidException){MessageBoxHelper.ShowError(e.Message);}else{var ef = new FrmException(e);ef.ShowDialog();ef.Dispose();}DebugHelper.Catch(e.Message);}}}
常见使用场景
- 快速原形测试
重新下面的函数,可以实现快速原形测试
public override Form GetLoginForm(){return null;}public override Form GetMainForm(){return new Form1();}
- 临时修改系统配置
public override WinFormSetting GetSetting(){var setting = base.GetSetting();setting.ApiUrl = "";//临时修改服务器根Urlsetting.ApiTimeout = 3000;//临时修改超时时间//修改其他属性值return setting;}
- 固定账号登录
public override BoolMessage<SysUser> UserLogin(string account, string password, string captcha){var user = new SysUser{Id = "123456780", //用户主键Account = "admin", //用户账号Name = "管理员" //用户姓名};//使用固定账号登录,实现快速登录return new BoolMessage<SysUser>(true,user);}
运行时对象
系统启动成功后,会把启动过程中产生的各种对象都保存在SysRuntime对象下面,这是一个静态类。
在后续的业务处理中有需要的时候直接调用SysRuntime的静态属性或者静态方法。
namespace XCI.Sys{/// <summary>/// 应用程序运行时数据/// </summary>public static class SysRuntime{/// <summary>/// 启动参数/// </summary>public static string[] StartupArgs { get; set; }/// <summary>/// 当前应用程序对象/// </summary>public static IApp App { get; set; }/// <summary>/// 服务器名称/// </summary>public static string ServerName { get; set; }/// <summary>/// 应用程序设置/// </summary>public static WinFormSetting Setting { get; set; }/// <summary>/// 登陆窗口/// </summary>public static Form LoginForm { get; set; }/// <summary>/// 主窗口/// </summary>public static Form MainForm { get; set; }/// <summary>/// 启动屏幕类型/// </summary>public static Type SplashScreenType { get; set; }/// <summary>/// 加载等待窗体类型/// </summary>public static Type WaitFormType { get; set; }/// <summary>/// 业务接口操作对象/// </summary>public static WebApi Api { get; set; }/// <summary>/// 当前应用程序登陆用户/// </summary>public static SysUser CurrentUser { get; set; }/// <summary>/// 添加主页面文档/// </summary>/// <param name="code">编码</param>/// <param name="form">窗体</param>public static void AddTabDocument(string code, Form form);/// <summary>/// 是否有指定模块编码的权限/// </summary>/// <param name="codes">模块编码集合</param>/// <returns>存在返回true,否则返回false</returns>public static bool IsAuthorize(params string[] codes);}}
