2023年2月

工作流是集成系统的模块应用,使用权限管理系统的身份认证登录后即可使用。本篇随笔介绍工作流模块的界面功能效果。

1、我的审批工作

我的审批工作,包括【我发起的】、【我的待办】、【我的已办】几类大项,并可以根据查询条件进行过滤列表,界面如下所示:

双击申请单,可以打开查看详细的申请单信息,如下界面所示。

如果审批单可以进行审批处理,则会出现相关的审批按钮,单击【审批】按钮,弹出审批对话框,可以录入相关的审批意见,如下界面所示。

如果表单需要撤销,单击【撤销】按钮,会弹出申请单撤销的确认界面,在其中录入撤销意见确认即可。

如果需了解申请单的流程日志信息,单击【流程日志】按钮,弹出申请单的相关日志信息,如下界面所示。

2、业务受理列表

业务受理列表展示当前工作流模块中可以创建的申请表单入口,如下界面所示。

我们可以根据左侧树列表的业务分类进行过滤,展示不同分类的申请单。单击其中图形按钮,可以创建一个新的申请单,申请单界面如下所示。

有些是简单的单表信息,有些则是主从表的明细表单,不同的表单界面,需要在开发模式进行开发处理。

3、我的草稿

我的草稿是保存用户尚未完成的申请单,在用户编辑申请单的时候,可以暂存在草稿里面,方便下次继续完成填写工作。我的草稿列表界面如下所示。

双击草稿列表的申请单,可以打开申请单的填写界面,如下所示。

4、已办业务查询

已办业务查询,按照不同的业务分类,展示相关申请单的列表,列表界面如下所示。

双击列表记录,可以查看具体的申请单详细信息。

5、流程模板

前面介绍过的工作流的业务受理列表,展示的是可以创建申请单的图形按钮列表,如下界面所示的效果列表。

其中的数据就是在这个流程模板中配置管理的,流程模板中管理工作流业务中可以使用的申请单配置信息,流程模板界面如下所示。

其中详细的配置窗体界面如下所示,这里配置框架处理中所需的相关参数数据,以及配置的流程节点。

单击【流程设置】,可以设置该申请单模板的流程步骤,如下界面所示。

6、流程环节管理

流程环节管理,是定义系统工作流中用到的流程环节类型(处理类型)信息,如下界面所示。

其中有常规的审批、归档、会签、阅办等操作,工作流需要根据这些流程类型来显示不同的处理界面。双击记录,可以进行编辑修改处理。

7、所有申请单

所有申请单列出工作流系统中的所有流程表单的信息,便于管理员针对性的查找申请单信息进行调整处理。

双击申请单列表,可以打开具体的申请单进行查看详细信息,如下所示。

8、流程审批操作

对于一个流程处理操作,我们知道一般有审批通过、拒绝、退回到某步骤、转发到内部阅读、阅读,以及包括起草者能撤销表单呢等操作,当然如果还有一些具体的业务,可能还会有一些流程的处理才操作,不过基本上也可以归结为上面几种,只是他们每步处理的数据内容不同而已。因此审批的操作步骤分类如下所示。

这些操作我们都可以通过一些界面操作的封装实现,因为他们基本上都是通用的,我们传入一些流程
ID等相关标识后,就能交给这些标准的操作界面完成了。

如审批界面如下所示,里面包含了通过、拒绝,跳回到某步骤,增加步骤等。

上面的界面是审批过程中,对于某一个流程处理人员实现的操作,而有时候,我们可能需要针对多个人进行某个步骤的处理,如会签处理,会签处理处理界面效果如下所示。

以及传递给内部人员进行分阅操作,那么就应该选定多个人员进行处理,大概的处理界面效果如下所示。

当然,若申请人的申请单填写错误,需要撤销的话,那么也应该有这个操作,撤销表单后,就可以重新填写表单,然后再次提交进行流程。

9、流程会签处理

会签是指创建一个或多个子流程供相关人员进行审批,等待全部人员完成处理后再次回到主流程上,然后决定是否继续流转到下一个流程步骤上去,一般的申请单的主流程如下所示。

这里设置的会签处理就是其中一个步骤,一旦会签处理步骤发起会签,就会构建多个可供审批的子流程了,如下所示。

在会签发起的步骤,指定参与具体流程会签审批的人员,然后流程则会流转到不同人员进行相关的处理【待办事项】。

我在工作流中定义会签完成后,由会签发起人审核(会签结果审核),决定是否进入下一步流程,在审核过程中决定如何处理这个申请单。

在流程定义里面,我们创建一个会签的流程步骤,我们以请假单为例,加入我们要求请假需要由各组长会签通过,然后在继续下面的部门审批、总经理审批步骤,如下所示。

增加会签后的流程步骤如下所示。

完成后可以在流程步骤列表中看到会签的步骤了,如下所示。

我们创建一个请假申请单,用来发起会签处理,介绍会签的步骤说明。

完成请假单后提交给相关处理人,处理人员在待办事项中查看申请单,如下界面所示。

那么他会发起【发起会签】的处理操作,把相关的投票权发送给各个组长进行会签处理。

会签发起后,各个参与会签的人员在【待办事项】里面处理会签意见,如下所示。

各个待审批的人员进行处理后,最后返回给会签发起人决定是否进入下一步流程,如下所示。

系列文章:


基于SqlSugar的开发框架的循序渐进介绍(1)--框架基础类的设计和使用


基于SqlSugar的开发框架循序渐进介绍(2)-- 基于中间表的查询处理


基于SqlSugar的开发框架循序渐进介绍(3)-- 实现代码生成工具Database2Sharp的整合开发


基于SqlSugar的开发框架循序渐进介绍(4)-- 在数据访问基类中对GUID主键进行自动赋值处理


基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转


基于SqlSugar的开发框架循序渐进介绍(6)-- 在基类接口中注入用户身份信息接口


基于SqlSugar的开发框架循序渐进介绍(7)-- 在文件上传模块中采用选项模式【Options】处理常规上传和FTP文件上传


基于SqlSugar的开发框架循序渐进介绍(8)-- 在基类函数封装实现用户操作日志记录


基于SqlSugar的开发框架循序渐进介绍(9)-- 结合Winform控件实现字段的权限控制


基于SqlSugar的开发框架循序渐进介绍(10)-- 利用axios组件的封装,实现对后端API数据的访问和基类的统一封装处理


基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结


基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理


基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用


基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用


基于SqlSugar的开发框架循序渐进介绍(15)-- 整合代码生成工具进行前端界面的生成


基于SqlSugar的开发框架循序渐进介绍(16)-- 工作流模块的功能介绍


基于SqlSugar的开发框架循序渐进介绍(17)-- 基于CSRedis实现缓存的处理


基于SqlSugar的开发框架循序渐进介绍(18)-- 基于代码生成工具Database2Sharp,快速生成Vue3+TypeScript的前端界面和Winform端界面

Winform界面中,有时候,需要对界面进行一些多语言的处理,以适应客户场景的使用,如有时候需要考虑英文、日文、韩文等客户的使用,那么在Winform界面如何实现这种多语言的正常处理呢,本篇基于Winform开发框架的基础上介绍使用多语言的处理过程。

1、多语言的处理思路

在国际化环境下,越来越多的程序需要做多语言版本,以适应各种业务需求的变化。在Winform应用程序中实现多语言也有常规的处理方式处理,不过需要针对每个语言版本,重新修改Winform界面的显示,对一些常规的辅助类,也需要引入一个统一的资源管理类来处理多语言的问题,相对比较繁琐。

我们的Winform开发框架,主要为了简化多语言的处理,编写了一些辅助的处理类库,读取对应的JSON多语言对键值对应文件,实现多语言的切换处理。

我们在开始编写程序的时候,使用我们熟悉的中文,然后在百度翻译(
https://fanyi.baidu.com/
)或者Google翻译对应的内容,存储在对应的目录中。

程序运行的时候,加载对应目录json文件即可实现多语言的处理。

首先我们开发系统的时候,需要创建一些多语言的对应目录,具体的目录我们遵循约定规则即可。

为了便于我们的处理,我们以中文为键,其中JSON里面对应的中文和其他语言的翻译结果,如下面是日文的参考内容。

我们记得把JSON文件,始终复制到目录上或者如果较新则复制,

这个目录就是会输出到debug或者Release的运行目录中,我们就是根据相对于运行目录进行资源读取即可,所有模块共用同一的多语言文件,我们可以把各个模块基础通用的多语言文件放在Basic.json文件中,也可以根据模块独立起名。

实际上目录名称是为了区分而已,程序加载的时候,会把目录下面所有的JSON文件进行加载,读取里面的键值作为资源的字典参照。

我们以我们常规的母语开发,即使我们不做多语言,也不影响代码的正常处理,我们只需要把窗体上和代码里面的中文提取出来,然后进行多语言处理(如变为英文/韩文/日文)即可。

2、多语言的处理效果

为了便于体验多语言的切换实际效果,我这里编写了一些测试的案例,并准备了中文、英文、日文、韩文的对照JSON文件,默认界面效果如下。

切换到英文的时候,界面如下所示。

控件英文界面效果

其他英文测试界面

切换韩文界面效果如下所示

其他视图界面效果

日文界面效果如下。

为了更好的测试其他控件的多语言处理,我们编写了一些控件的展示界面如下GridControl,TreeList等控件。

效果都没有问题,来回测试测试也是正常,符合要求。

3、多语言的代码处理

看完实际的效果,那么我们需要如何在代码中处理,才能实现多余的正常切换呢。

首先我们为了记住用户选择的语言区域信息,我们在配置文件中增加一个键值用来保存区域代码。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <addkey="CultureInfo"value="en-US" />
  </appSettings>

然后切换语言的时候,编写处理语言的切换和区域的存储即可,如下所示。

        /// <summary>
        ///改变界面的语言/// </summary>
        /// <param name="lang"></param>
        private void ChangeLang(stringlang)
{
if (lang == "cn")
{
System.Threading.Thread.CurrentThread.CurrentUICulture
= new System.Globalization.CultureInfo("zh-Hans");
config.AppConfigSet(
"CultureInfo", "zh-Hans");
}
else if (lang == "kr")
{
System.Threading.Thread.CurrentThread.CurrentUICulture
= new System.Globalization.CultureInfo("ko-KR");//韩文界面 config.AppConfigSet("CultureInfo", "ko-KR");
}
else if (lang == "en")
{
System.Threading.Thread.CurrentThread.CurrentUICulture
= new System.Globalization.CultureInfo("en-US");//英文界面 config.AppConfigSet("CultureInfo", "en-US");
}
else if (lang == "jp")
{
System.Threading.Thread.CurrentThread.CurrentUICulture
= new System.Globalization.CultureInfo("ja-JP");//日文界面 config.AppConfigSet("CultureInfo", "ja-JP");
}

LanguageHelper.Reload();
//重新初始化JSON资源 LanguageHelper.InitLanguage(this, true);//刷新界面控件 }

上面的
LanguageHelper
辅助函数,主要就是用来对界面进行多语言处理的。

为了方便,我们的封装的基类窗体BaseForm、BaseEditForm、BaseDock等基础窗体,我们一般在界面初始化的时候,都会调用
LanguageHelper
辅助函数来进行界面的多语言处理。

因此,如果是采用我们的基类窗口,那么默认就带有多语言的处理功能了,我们按照约定规则,处理好对应的多语言翻译文件JSON文件即可。

如果是对于一些自定义的窗体,或者继承默认的窗体类,那么在构造函数完成处理的时候,可以增加一行代码来处理多语言,如上面的规则所示即可。

这样也就能实现多语言的处理了

在一个应用系统的开发框架中,往往很多地方需要用到缓存的处理,有些地方是为了便于记录用户的数据,有些地方是为了提高系统的响应速度,如有时候我们在发送一个短信验证码的时候,可以在缓存中设置几分钟的过期时间,这样验证短信验证码的时候,就会自动判断是否过期了。本篇随笔结合CSRedis的使用,介绍如何实现缓存的初始化及使用的处理。

1、在基于.netCore的Web API后端使用CSRedis

关于CSRedis的使用,我们可以参考Github网站:
https://github.com/2881099/csredis
进行了解。

首先我们在使用前,需要添加对应的程序集应用。

Package Name NuGet Downloads
CSRedisCore nuget stats
Caching.CSRedis nuget stats IDistributedCache

CSRedisCore是必须的,而Caching.CSRedis则是在用到分布式缓存的时候需要用到。

初始化CSRedis也比较简单,如代码所示。

var csredis = new CSRedis.CSRedisClient("127.0.0.1:6379,password=123,defaultDatabase=13,prefix=my_");

不过我们的Redis配置一般放在appSettings.json文件中,不是直接硬编码的,所以需要调整一下。

//初始化Redis及分布式缓存
var redisConnectionString = builder.Configuration["CSRedis:ConnectString"];
RedisHelper.Initialization(
newCSRedisClient(redisConnectionString));
builder.Services.AddSingleton
<IDistributedCache>(new CSRedisCache(RedisHelper.Instance));

常规的缓存设置,通过键、值、时间设置等几个内容进行处理,如下代码所示。

RedisHelper.Set("test1", "123123", 60);

RedisHelper.Get(
"test1");

如果我们要清空所有的缓存键值,那么对键进行模式匹配进行处理即可。

/// <summary>
///清空Redis缓存/// </summary>
protected voidClearRedisCache()
{
//查找所有分区节点中符合给定模式(pattern)的 key var cacheKeys = RedisHelper.Keys("*");
RedisHelper.Del(cacheKeys);
}

除了常规的缓存处理,redis也支持消息队列的处理,消息队列最熟悉无疑是 rabbitmq,它基本是业界标准的解决方案。另外 redis 也提供了多种实现轻订阅方法。如下面是一案例代码。

//程序1:使用代码实现订阅端
var sub = RedisHelper.Subscribe(("chan1", msg =>Console.WriteLine(msg.Body)));//sub.Disponse();//停止订阅//程序2:使用代码实现发布端
RedisHelper.Publish("chan1", "666666");

我们这里不深究消息队列的处理,有兴趣的可以参考文章《
【由浅至深】redis 实现发布订阅的几种方式
》进行了解即可。

2、前端发送短信验证码及后端判断

我们这里以一个短信验证码登录的前端来介绍CSRedis缓存的设置、获取、移除等操作过程。

例如,我们的移动前端,需要验证码登录系统的时候,需要发送验证码的操作,如下所示。

前端通过初步判断手机号码正确后,可以向后端请求发送验证码,如下逻辑代码所示(vue)

//获取验证码
getCode() {if (this.model.mobile.length < 11 && !uni.$u.test.mobile(this.model.mobile)) {
uni.$u.toast(
'手机号码不正确')return;
}
//发送短信验证码 var params ={
PhoneNumber:
this.model.mobile
}
user.SendPhoneLoginSmsCode(
params).then(res =>{if(res.success) {this.show = false;
uni.$u.toast(`验证码已发送至手机 ${
this.model.mobile},请注意查收!`)

let interval
= setInterval(() =>{this.second--;if (this.second <= 0) {this.show = true;
clearInterval(interval);
}
},
1000);
}
else{
uni.$u.toast(
'发送出现错误:' +res.errorMessage)
}
})
}

WebAPI后端,处理逻辑是构建随机的验证码并通过短信发送到手机上,并缓存好对应的验证码,后端的处理代码如下所示

/// <summary>
///发送登录动态码/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpPost]
[Route(
"send-login-smscode")]public async Task<CommonResult>SendPhoneLoginSmsCode(PhoneCaptchaModel model)
{
//获取随机6位数字动态验证码 var code = RandomChinese.GetRandomNumber(6);//使用自定义模板处理短信发送 string message = string.Format(ConfigData.MySmsCodeTemplate, code);var result = await_smsSender.SendAsync(model.PhoneNumber, message);if(result.Success)
{
var cacheKey = model.PhoneNumber;//以手机号码作为键存储验证码缓存 var cacheItem = new SmsLoginCodeCacheItem { Code = code, PhoneNumber =model.PhoneNumber };

RedisHelper.Set(cacheKey, cacheItem, TimeSpan.FromMinutes(ConfigData.SmsCodeExpiredMinutes));
//获取的时候//var tmp = RedisHelper.Get<SmsLoginCodeCacheItem>(cacheKey); }returnresult;
}

顺利发送短信验证码后,前端会提示用户验证码发送情况,并要求输入验证码进行登录,前端登录的代码如下所示。

//短信验证码登录
loginByCode() {var params ={
mobile:
this.model.mobile,
smscode:
this.model.code
};
console.log(params);
user.dynamiclogin(params)
.then(res
=>{
uni.$u.toast(
'验证成功');this.gotoPage();
})
.
catch(error =>{
console.log(
'验证失败' +error);
uni.$u.toast(error);
});
},

后端的登录处理,主要就是通过在Redis中读取对应的手机验证码,如果匹配进行令牌的生成处理,否则提示错误信息。

/// <summary>/// 登录授权处理/// </summary>/// <returns></returns>
[AllowAnonymous]
[HttpPost]
[Route(
"authenticate-byphone")]
public async Task
<AuthenticateResultDto>AuthenticateByPhoneCaptcha(PhoneCaptchaModel model)
{
var authResult = newAuthenticateResultDto();
#region 条件检查
if(string.IsNullOrEmpty(model.PhoneNumber))
{
throw new MyApiException("手机号不能为空");
}
if(string.IsNullOrEmpty(model.SmsCode))
{
throw new MyApiException("验证码不能为空");
}
var userInfo = await _userService.GetFirstAsync(s => s.MobilePhone ==model.PhoneNumber);if (userInfo == null)
{
throw new MyApiException("用户手机不存在");
}
#endregion
var cacheKey = model.PhoneNumber;//以手机号码作为键存储验证码缓存 var item = RedisHelper.Get<SmsLoginCodeCacheItem>(cacheKey);if (item != null && item.Code ==model.SmsCode)
{
//根据用户身份生成tokenresult authResult.AccessToken = GenerateToken(userInfo); //令牌 authResult.Expires = expiredDays * 24 * 3600; //失效秒数 authResult.Success = true;//成功 authResult.UserId = userInfo.Id;//当前用户Id //移除缓存短信键值 RedisHelper.Del(cacheKey);
}
else{
authResult.Error
= "登录失败,无法生成令牌";
}
returnauthResult;
}

如果顺利生成令牌,则从redis中移除对应的缓存键值即可。

如果我们需要查看Redis的缓存内容,Windows端可以安装 RedisDesktopManager 进行查看管理Redis的内容。

发送短信后,键值会保存在Redis缓存中,可以通过RedisDesktopManager  进行查看。

手机端顺利收到短信提示。

以上就是关于在SqlSugar的开发框架,通过介绍短信验证码的前后端协作方式,介绍使用CSRedis实现缓存的处理过程。

系列文章:


基于SqlSugar的开发框架的循序渐进介绍(1)--框架基础类的设计和使用


基于SqlSugar的开发框架循序渐进介绍(2)-- 基于中间表的查询处理


基于SqlSugar的开发框架循序渐进介绍(3)-- 实现代码生成工具Database2Sharp的整合开发


基于SqlSugar的开发框架循序渐进介绍(4)-- 在数据访问基类中对GUID主键进行自动赋值处理


基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转


基于SqlSugar的开发框架循序渐进介绍(6)-- 在基类接口中注入用户身份信息接口


基于SqlSugar的开发框架循序渐进介绍(7)-- 在文件上传模块中采用选项模式【Options】处理常规上传和FTP文件上传


基于SqlSugar的开发框架循序渐进介绍(8)-- 在基类函数封装实现用户操作日志记录


基于SqlSugar的开发框架循序渐进介绍(9)-- 结合Winform控件实现字段的权限控制


基于SqlSugar的开发框架循序渐进介绍(10)-- 利用axios组件的封装,实现对后端API数据的访问和基类的统一封装处理


基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结


基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理


基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用


基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用


基于SqlSugar的开发框架循序渐进介绍(15)-- 整合代码生成工具进行前端界面的生成


基于SqlSugar的开发框架循序渐进介绍(16)-- 工作流模块的功能介绍


基于SqlSugar的开发框架循序渐进介绍(17)-- 基于CSRedis实现缓存的处理


基于SqlSugar的开发框架循序渐进介绍(18)-- 基于代码生成工具Database2Sharp,快速生成Vue3+TypeScript的前端界面和Winform端界面

我们开发一个系统,在保证风格统一、代码强壮、可读性强等基础上,还能够结合代码生成工具快速开发相关后端,以及各种前端界面的,无疑是非常好的,既保证了项目的代码质量,又能够极大的提高开发效率。代码生成工具Database2Sharp是在完善的开发项目上,抽取出数据变化的部分,通过演绎、归纳、反复演绎和归纳等提炼方式抽取出相关的规则,以工具的方式来快速提高生产率,使得我们在开发各种不同的项目上的时候,能够事半功倍,本篇随笔介绍基于代码生成工具Database2Sharp,快速生成Vue3+TypeScript的前端界面和Winform端界面。

1、代码生成工具Database2Sharp的使用

对于SQLSugar的项目框架,我们为了方便,分别单独提供后端代码和Web API代码的生成、Winform界面代码的生成,以及前面介绍到的Vue3+TypeScript+ElementPlus的代码生成操作。

代码生成工具的界面效果如下所示,通过入口菜单,可以实现不同部分的代码快速生成。

2、Vue3+TypeScript的前端界面代码生成

Vue3+TypeScript+ElementPlus前端界面,常规页面的内容的整体界面布局,它包含常规的列表界面,新增、编辑、查看、导入等界面,除了列表页面,其他内容以弹出层对话框的方式进行处理,如下界面示意图所示。

Vue3+TypeScrip最大的特点就是组件模块的便利性。

我们通过抽取共共性的内容组成组件,从而不同的页面内容,只需要维护不同的文件即可,从而隔离变化,提高代码的可读性和可维护性。

根据以上的页面划分,我们把一个页面分为search.vue、edit.vue、import.vue、view.vue、index.vue,其中index.vue为整合各个组件的主页面,在视图中如下所示。我们每个业务模块都是如此统一划分,因此比较统一,同时也是为后续的代码生成工具批量生成做好准备。

因此在index.vue页面中,我们整合了几个组件页面即可,如下所示。

<template>
  <divclass="main">
    <!--条件及列表展示-->
    <Searchref="searchRef"@show-import="showImport"@show-add="showAdd"@show-view="showView"@show-edit="showEdit" />

    <!--查看详细组件界面-->
    <view-dataref="viewRef" />
    <!--新增、编辑组件界面-->
    <edit-dataref="editRef"@submit="refreshData" />
    <!--模板导入信息-->
    <import-dataref="importRef"@finish="finishImport" />
  </div>
</template>

<scriptsetup lang="ts">import { reactive, ref, onMounted } from'vue';

import Search from
'./search.vue';
import ViewData from
'./view.vue';
import EditData from
'./edit.vue';
import ImportData from
'./import.vue';

这样我们只需要维护查询页面、编辑页面、查看页面、导入页面的内容就可以了,而这些主要反映在相关的字段信息上,大的方向上我们已经根据页面的布局设置好了。

常规的列表页面内容,包含一些查询条件,以及相关的入口按钮事件的处理,如下界面所示

而如果是需要显示树列表的内容,我们在代码生成的时候,选择树列表界面生成即可,大致效果如下所示。

最后页面效果如下所示。

查看详细的页面内容效果如下所示。

视图页面效果如下所示。

编辑界面的效果如下所示。

导入界面,一般我们分为几个步骤,一个是提供导入模板下载,然后上传文件并显示数据,然后确认提交即可。

由于导入数据的逻辑上大致类似,不同的是他们的业务数据和验证规则,因此我们通过自定义组件的方式,来简化

相关的处理。

我通过改造ele-import 的第三方组件,让它支持Vue3+Typescript语法,实现对业务数据的上传操作。】

通过隔离页面组件的内容变化,实现变化不同通过数据库表关系生成,固定部分采用规定模板预置内容,实现了代码的快速生成操作。

3、Winform端界面代码生成

和我们其他Winform界面一样,Winform项目的界面代码生成,生成包括普通的列表界面,以及主从表Winform界面代码生成。Winform界面的生成已经非常成熟,我们只需要替换一下数据请求的处理即可,常规的实体类,接口等内容,通过SqlSugar开发框架生成后,引入相关的程序集使用即可。

Winform项目大概情况如下所示。

Winform端本身已经包含了完善的权限管理、字典管理、附件管理、综合案例,以及工作流管理等内容。

用户操作日志信息如下所示。

工作相关界面如下所示。

而我们基于代码生成工具的Winform界面快速生成,也是基于成熟的Winform开发经验和界面效果来规范化的。

SqlSugar的项目基础核心数据模块SugarProjectCore,主要就是开发业务所需的数据处理和业务逻辑的项目,为了方便,我们区分Interface、Modal、Service三个目录来放置不同的内容,其中Modal是SqlSugar的映射实体,Interface是定义访问接口,Service是提供具体的数据操作实现。

WInform界面生成的界面效果如下所示,通过选定不同的字段,定制化界面效果。

生成的简单业务表界面,包括分页列表展示界面,在列表界面中整合查看、编辑、新增、删除、导入、导出、查询/高级查询等功能,整合的编辑界面也是依据数据库表的信息进行生成的。

列表界面和编辑界面效果如下所示。

而主从表界面生成的效果如下所示。

我们看看生成的Winform列表界面代码,如下所示。

另外我们把一些常用的处理逻辑放在函数中统一处理,如AddData、EditData、DeleteData、BindData、GetData、ImportData、ExportData等等,如下所示。

如需要下载测试代码生成工具
Database2sharp
,请到官网
https://www.iqidi.com/database2sharp.htm
下载试用。

在之前的SqlSugar系列随笔中,介绍了很多我们关于SqlSugar的开发框架的内容,SqlSugar的开发框架的目的是多前端应用场景,因此其中会包含各种不同的前端应用,前面介绍了基于DevExpress的Winform的前端应用,以及基于Vue3+TypeScript+ElementPlus的BS前端应用,本篇随笔继续介绍SqlSugar的开发框架的另一个前端应用,基于UniApp+Vue+ThorUI的移动前端。

1、基于UniApp+Vue+ThorUI的移动前端

前端开发,可以是基于Vue&Element的管理后台的前端开发,也可以是Vue + UniApp+手机端组件库的开发H5或者App应用,技术路线都是基于Vue的,我们这里主要介绍UniApp+HBuliderX+Vue+ThorUI来开发H5端的应用。

UniApp
是一个使用
Vue.js
开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。

使用UniApp的主要原因是它的生态比较完善,而且提供了不同平台的统一的接口调用方法,因此非常方便使用它来统一构建多端应用。

使用UniApp,为了集成方便,一般也会使用HBuilderX开发工具来进行前端的开发。
HBuilderX
编辑器是DCloud全新推出的一款HTML5的Web开发工具。HBuilder目前有两个版本,一个是windows版,一个是mac版。下载的时候根据自己的电脑选择适合自己的版本即可。如果不考虑深度集成的原因,还可以考虑使用更加广泛的VS Code编辑器,毕竟VS Code可是前端界的开发标准工具了。

另外UniApp也有自己的组件库,同时也做的很不错,不过由于参照模板的问题,我们这里使用了会员版的
Thor UI
,可以参考的案例更多,方便做出更好的界面效果。

Thor UI
是一款开发移动端网页应用、小程序的前端 UI 组件库,uni-app 版本还可以编译成为安卓/ iOS APP 应用,特点是轻量、简洁,组件覆盖比较全面,使开发更高效。Thor UI目前有微信小程序原生版本 (opens new window)和uni-app版本。

SqlSugar开发框架主要的设计模块场景如下所示。

1)其中一些常用的类库,以及SqlSugar框架的基类放在框架公用模块里面。

2)Winform开发相关的基础界面以及通用组件内容,放在基础Winform界面库BaseUIDx项目中。

3)基础核心数据模块SugarProjectCore,主要就是开发业务所需的数据处理和业务逻辑的项目,为了方便,我们区分Interface、Modal、Service三个目录来放置不同的内容,其中Modal是SqlSugar的映射实体,Interface是定义访问接口,Service是提供具体的数据操作实现。其中Service里面一些框架基类和接口定义,统一也放在公用类库里面。

4)Winform应用模块,主要就是针对业务开发的Winform界面应用,而Winform开发为了方便,也会将一些基础组件和基类放在了BaseUIDx的Winform专用的界面库里面。

5)WebAPI项目采用基于.net Core 的项目开发,通过调用SugarProjectCore实现相关控制器API的发布,并整合Swagger发布接口,供其他前端界面应用进行调用。

6)纯前端通过API进行调用Web API的接口,纯前端模块可以包含Vue3&Element项目,以及基于EelectronJS应用,发布跨平台的基于浏览器的应用界面,以及其他H5应用、App应用或者小程序应用模块,整合Web API进行业务数据的处理或者展示。

其中Web API的Swagger接口管理界面如下。

Winform端的前端界面如下所示。

Vue3+Typescript+ElementPlus的前端界面如下所示。

而基于Web API的移动端UniApp应用(HbuilderX开发工具)的开发项目界面效果如下所示。

2、UniApp+Vue+ThorUI的移动前端功能介绍

了解了大概的项目架构和技术路线后,我们来看看移动端的功能介绍。

和其他前端的功能配套,那么我们移动前端也可以管理一些系统的数据,如用户、机构、角色、字典等等信息,以及一些额外的业务数据处理,如一些业务基础数据的录入,业务的审核,业务统计报表等功能。

1)用户登录

移动前端用户通过账号密码进行登录(也可以选择短信验证码方式登录)后台管理系统,登录界面如下所示。

用户输入系统正确的账号、密码,即可顺利登录系统,系统根据用户所属角色和分组信息,展示用户能够管理的功能页面。系统默认展示首页视图。

2)忘记密码

如果用户忘记自己的账号密码,可以通过手机验证码方式进行重置密码操作。

3)重设密码、修改用户资料

登录系统成功后,在系统右上角的图像按钮中,可以进行用户密码修改,也可以在编辑按钮或者图标中进入用户信息编辑处理界面,界面效果如下所示。

如需修改用户头像,单击头像图片,图片选择确认后上传图片进行头像修改。

4)修改手机号码

如需修改手机号码,单击手机号栏目,可以进行手机号码的修改调整,手机修改需要接受短信验证码,输入成功后才能更新该用户的手机号码。

5)注册账号

由使用人员使用手机和手机验证码自己申请注册用户,由系统管理员审核同意后,创建并分配系统用户,一个手机号码只能申请一次。

注册账号的界面如下所示。

6)注册用户审核

系统管理员登录后,可以在管理功能中进行注册用户的管理操作,如下界面所示。

单击用户列表,弹出审核对话框,审核通过后,系统将创建指定相关信息的用户账号,可以使用该账号和初始密码进行登录。拒绝申请则不再接收该用户的注册,系统不创建账号。

7)字典管理

字典管理是一个通用的字典大项、字典项目的维护管理,便于系统下拉列表以及相关参考值的维护,字典管理界面如下所示。

这样在具体页面中就可以直接使用字典项目信息了,如下树形列表和下拉项目所示。

为了方便,在手机前端为管理员提供一个维护常规字典类型和字典项目的入口,在【管理工具】【字典维护】入口进入,如下所示。

单击其中字典大类,可以进行查看或者编辑对应字典大类下的项目信息,如下界面所示。

如需要对字典大类的信息进行维护,可以单击顶部修改的按钮,对字典大类的信息进行编辑处理,如下编辑界面所示。

8)我的地址簿

为了方便管理一些地址信息,系统提供了一个通用的地址簿进行管理,可以录入常见的地址信息,如下界面所示。

新增或者对已有记录进行编辑,可以进入界面如下所示。

9)新闻资讯

在个人信息页面中,里面有一个资讯中心,展示一些新闻资讯,如下所示。

单击可以或查看更多的列表,可以查看详细的新闻咨询信息,详细信息页面如下所示。

10)系统用户维护

系统管理员用户可以登录后,进行系统用户的维护,包括对用户进行查询,以及用户密码重置、用户过期/用户恢复的设置处理。

在管理工具入口,单击系统用户即可进行用户的搜索处理。

滑动用户列表,可以对用户进行密码重置、设置过期、用户恢复操作。

或者单击用户记录,可以对指定用户进行相关的
用户密码重置、用户过期/用户恢复
的设置处理。


11)组织机构管理

在管理面板中找到【组织机构】入口,如下图所示。

页面分层列出整个公司部门的组织机构,示例组织机构如下所示,实际根据自己的系统进行创建。

单击特定的机构节点,可以展开详细的机构信息,如下界面所示,管理员可以删除机构处理。

另外在底部有【新增机构】功能,单击可以进行创建机构信息。

在弹出的界面中,单击【父级机构】,可以展示当前机构的节点,选择机构作为父级,然后录入其他信息即可。

12)角色管理

角色管理包括角色查看、角色创建、以及分配角色用户几个功能。

在管理面板中找到【角色管理】入口,如下图所示。

角色是以公司进行划分的,因此查看角色需要选择特定的公司节点,如下所示。

单击公司节点,可以查看任一公司的角色列表,如下界面所示。

单击角色节点,可以查看角色的详细信息,或者删除角色,如下所示。

也可以在底部【新增角色】,弹出如下界面,录入提交即可创建新角色。

或者在角色包含的用户列表中,可以选择【移除角色用户】,或者【添加新用户】到角色中。

选择【添加】按钮,会弹出新的选择用户列表界面,选择加入用户即可完成角色用户的添加。

13)业务数据管理

不同的业务系统,我们需要创建一些不同的业务表单数据进行录入、查询等操作。

业务数据,可以在管理列表中根据关键字进行查询,列表界面下所示。

以上就是一个移动端的业务应用的系统界面,主要的目的是能够快捷的收集或者处理常规的业务数据,也便于后台管理系统的数据维护。

系列文章:


基于SqlSugar的开发框架的循序渐进介绍(1)--框架基础类的设计和使用


基于SqlSugar的开发框架循序渐进介绍(2)-- 基于中间表的查询处理


基于SqlSugar的开发框架循序渐进介绍(3)-- 实现代码生成工具Database2Sharp的整合开发


基于SqlSugar的开发框架循序渐进介绍(4)-- 在数据访问基类中对GUID主键进行自动赋值处理


基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转


基于SqlSugar的开发框架循序渐进介绍(6)-- 在基类接口中注入用户身份信息接口


基于SqlSugar的开发框架循序渐进介绍(7)-- 在文件上传模块中采用选项模式【Options】处理常规上传和FTP文件上传


基于SqlSugar的开发框架循序渐进介绍(8)-- 在基类函数封装实现用户操作日志记录


基于SqlSugar的开发框架循序渐进介绍(9)-- 结合Winform控件实现字段的权限控制


基于SqlSugar的开发框架循序渐进介绍(10)-- 利用axios组件的封装,实现对后端API数据的访问和基类的统一封装处理


基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结


基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理


基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用


基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用


基于SqlSugar的开发框架循序渐进介绍(15)-- 整合代码生成工具进行前端界面的生成


基于SqlSugar的开发框架循序渐进介绍(16)-- 工作流模块的功能介绍


基于SqlSugar的开发框架循序渐进介绍(17)-- 基于CSRedis实现缓存的处理


基于SqlSugar的开发框架循序渐进介绍(18)-- 基于代码生成工具Database2Sharp,快速生成Vue3+TypeScript的前端界面和Winform端界面


基于SqlSugar的开发框架循序渐进介绍(19)-- 基于UniApp+Vue的移动前端的功能介绍