1 Star 6 Fork 3

鸿鹄(深圳)创新技术有限公司 / gooderp低代码框架erp.mes.oa流程系统

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

gooderp低代码erp.mes.oa系统

介绍

  鸿鹄创新长期专注于企业资源计划ERP、智能制造、系统集成等企业信息化相关领域,为客户提供深入和长期的顾问咨询、客户化定制开发及配套的系统服务。经过多年研发,打造了gooderp低代码平台,平台简单易用,集成工作流和智能硬件接口,可以快速为企业量身定制各种管理系统,并根据中小企业需求实现了ERP系统,可以自由定义适配多个行业的中小企业。 输入图片说明

软件架构

软件架构说明 开发环境要求

操作系统:Windows 11

开发工具:Visual Studio 2020

SDK:安装.NET Core6及以上

数据库:mysql 8及以上

分层架构 输入图片说明 总体架构 输入图片说明

框架组成结构一共分为5层,如上图所示,分别如下:

基础设施层:此层为最底层,可以为其余所有层服务。主要提供了项目开发所需的各种帮助类:数据库访问帮助类、文件操作帮助类、二维码生成帮助类、分拣压缩帮助类等等其余帮助类;拓展类:字符串拓展类、集合操作拓展类、表达式树拓展类等等其余拓展类;还集成了个人编写的Socket通讯框架,WCF拓展使用框架,Windows服务容器。这些丰富的类库都是为开发人员提供了开发中常用的功能,为快速开发提供强有力的保障。

数据仓储层:这层主要为对数据库操作CRUD的简单封装,以EntityFramework为核心,采用简单工厂、抽象工厂、工厂方法、三个工厂设计模式,使开发人员进行CRUD只需要极为简单的代码即可完成。本层还提供了数据库事务的支持,更是提供了分布式事务支持,为数据库操作提供必备的保障,并且支持数据库读写分离分库分表。使用本层提供的接口,无需关心具体的数据库类型,比如是采用SQLServer数据库或者MySQL数据库,开发人员只需要关心具体的业务逻辑实现,哪怕更换数据库,也无需更改业务逻辑代码,只需要更改简单的数据库配置即可。总之,本层为开发人员对数据库的操作提供了简单高效的操作接口,可以极大的提高开发效率。

实体层:这层主要为ORM框架数据库表对应的实体类,为业务逻辑层和应用层服务。

业务逻辑层:本层是开发人员主要编写层,通过调用数据仓储层操作数据库,并为应用层提供所需的接口,处理具体操作的业务逻辑,可以说是最为复杂的一层。

应用层:本层在本框架中表现形式为ASP.NET MVC网站,其实也可以泛指其余的表现形式:控制台程序、Windows服务程序、WinForm程序、WPF程序等等。本层为具体的应用,负责系统功能的实现。

基础设施层 此层为最底层,可以为其余所有层服务。主要提供了项目开发所需的各种类库,主要为以下几种类库:

拓展帮助类 利用C#的语法糖(是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用),可以在类上拓展自定义方法,这样开发人员在使用的时候就可以十分的方便,既能减少重复的代码又能加快开发效率。具体包含但不限于以下类:

Object拓展:Object是所有类的基类。现在前后端数据交互中,采用JSON是选择,因此对象JSON序列化与反序列化的使用就十分的频繁,通过给Object拓展ToJson方法,就可以将数据对象直接转为对应的JSON字符串,能够极大的简化JSON序列化所需要的代码。

Byte拓展:Byte,即字节,一个字节是8个比特位,十进制数值范围在0-255。由于Byte与二进制是直接对应的,而计算机中一切数据都是二进制,所以关于Byte与其他数据类型之间的转换就显得尤为重要,编写Byte相关的拓展方法能够方便Byte的使用。例如,拓展将Byte数组转为16进制字符串的方法,能够将字节数组直接转为对应的16进制字符串,现在物联网的发展也十分的迅速,在物联网开发中,关键是建立与硬件之间的通信,但是由于硬件的配置一般都不高,因此与硬件之间的通信大多以字节为单位,这种情况下,使用该拓展方法就可以提高开发效率。

Expression拓展:Expression,即表达式树,在LINQ查询中经常使用。在日常使用中,Where筛选估计是用得最多的,但是大多数开发人员都是使用最原始的Where筛选,当筛选条件增多,筛选条件变复杂的时候,原始的Where虽然也可以胜任,但是就会导致代码重复,不够简洁雅观,此时可以为Expression< < Func< T, bool > >类拓展And与Or方法,其中And是“与”操作,Or是“或”操作,这样就可以将多个筛选条件拼接在一起,十分的实用。

IQueryable< T >拓展:IQueryable< T >是提供针对特定数据源(其中数据类型未未知)评估查询的功能接口,其在EntityFramework中发挥着重要的作用。例如,在后台管理系统中,数据表格的使用最为普遍,前端向后台请求表格数据时,不外乎需要以下几个参数:当前请求页码、每页记录数、排序列与排序类型,这些参数在每个请求表格数据请求中都需要处理,这时,通过给IQueryable < T >拓展GetPagination < T >方法,只需要传入分页参数,就可以获取所需的数据表格数据,十分的方便高效。

工具帮助类 主要提供了常用的一些帮助类,包含但不限于:

Office办公文档导入导出帮助类:当今,随着人们环保意识的增强,以及各行业对办公模式需求的不断升级,现代化、信息化建设步伐的加快,无纸化办公已经由概念逐渐应用到多个行业领域中,办公中,各种办公文件,尤其是Excel文件与Word文件经常需要导入与导出,但是C#操作Excel与Word文件并不简单,经常困扰着开发者,由此,本框架提供了Office文档操作帮助类,封装简化了对办公文档的常用操作,能够降低开发难度,提高开发效率。

HTTP请求模拟帮助类:在传统网站开发中,一般都是前端浏览器向后台发起请求,但是,现在的系统与系统之间的合作越来越紧密,经常需要后端向后端发起请求,即需要后端模拟HTTP请求,但编写一个完整的HTTP请求并不是那么容易,因此本框架提供HTTP请求帮助类,开发人员只需要传入需要请求的URL地址与参数即可完成HTTP请求操作,使用起来简单高效,能够极大的提高开发效率。

缓存操作帮助类 在现代化系统开发中,随着业务量的增大,系统性能就难以满足要求,要达到性能要求,一方面可以采用更好的硬件,但是成本较高,而另一方面就是使用缓存,有效使用缓存能够提高吞吐量与并发量,所需成本较低,是绝大多数用户的首选。 .NETFramework框架提供了系统缓存,虽然使用简单方便,但是不支持分布式,因此大多选择诸如Redis和Memcached缓存,但是不同的缓存为开发者提供的接口不一样,当使用不同的缓存时开发人员又需要去学习别的缓存操作接口,十分的麻烦,为解决这个问题,本框架提供了缓存操作帮助类。缓存操作帮助类将缓存核心操作抽象定义成操作接口:添加缓存、删除缓存、设置缓存过期时间,然后再用Redis与系统缓存实现抽象接口,当使用缓存时可以使用同样的操作接口操作不同的缓存,能够降低开发人员学习成本,提高开发效率。

数据库操作帮助类 无论什么网站,只要需要对数据进行操作,那么大多离不开数据库。数据库目前使用最多的就是三大关系型数据库:SQLServer、MySQL与Oracle,访问数据库需要一系列的程序:首先需要创建数据库连接对象,紧接着打开数据库,其次传入数据库操作命令,然后执行命令,最后得到数据结果,若每次访问数据库都要写一遍这些流程,那么将会极大的阻碍开发效率,因此,本框架提供了数据库操作帮助类,将数据库操作所需要的流程封装,开发人员只需要关心具体的SQL语句的编写即可,并且支持三大关系型数据库,适合不同的开发人员使用。

数据仓储层 在后端开发中,数据库操作是最频繁的,每一个后端开发人员或多或少都会接触,甚至不少开发人员每天的工作就是与数据库打交道,所以可见数据库操作是多么的重要。在现在开发的过程中,绝大多数开发人员只是以编写SQL语句的方式操作数据库,这种方式是操作数据库最基本最原始的方式,简单高效,但是在编写SQL语句的过程中,极容易因马虎大意而编写错误,就会出现一个现象:开发人员面对着一堆SQL语句在DEBUG,而且每次都需要开发人员自己去手写SQL语句,其开发效率极低。哪怕开发人员足够出色,能够保证编写的SQL语句较低的出错率,但是,不同的数据库所需要的SQL语句还是有差异的,这就需要开发人员学习不同的数据库SQL语法,添加学习成本。而且在项目开发中难免会遇到更换数据库的情况,这时还需要花费大量的精力去进行修改SQL语句。 在本框架的数据仓储层中,上述问题即可迎刃而解。数据仓储层,不同于传统三层架构中的数据层,其核心继承关系图如下图所示(图6-1):

数据仓储层类图

图6-1 数据仓储类图

如上图所示,首先定义了数据操作接口IRepository,该接口包含了增、删、改、查、事物控制等数据库常用核心操作,能够满足对数据库的常用操作,DbRepository类实现了IRepository接口,主要以ORM框架Entity Framework为基础,封装实现了大部分IRepository所需的操作,SqlServerRepository、MySqlRepository和PostgreSqlRepository分别实现具体数据库对应的数据仓储,而且继承自同一个数据操作接口IRepository,因此在具体的使用上,可以实现以同一个操作方法访问不同的数据库,当遇到需要更换数据库的情况时,采用本框架开发的系统能够不改代码而正常运行,这一点能够极大的降低软件开发成本。并且以Entity Framework为核心,不需要编写SQL语句就能够完成绝大部分的数据库操作,再加上简洁的LINQ配合,彻底将开发人员从SQL语句中解放出来,让开发人员能够更加专注于业务逻辑的实现,能够极大的提高软件开发效率。

数据实体层 由于框架主要采用了EntityFramework作为ORM框架,这其中数据库实体映射必不可少,需要将数据库中每张表映射到类中,并且一张表一个类。这些实体类即能够作为数据库操作中的实体,还能够作为DTO(Data Transfer Object),将这些实体类划分为独立的一层,能够方便对实体的管理,易于开发与维护。

业务逻辑层 在整个后端开发中,业务逻辑的处理是最复杂的,因为从技术角度来讲,很多技术都能够实现代码复用,即无需重复造轮子(重造轮子是重复创造一个已经存在的基本方法或者被其他人优化),而且只要会使用了就能够快速投入生产中,虽然技术可以从设计上实现代码重用,降低学习成本,但是不同的系统其业务逻辑通常是不可复制的,因此开发人员可以不关心具体数据仓储的实现技术,但是不得不关心具体业务逻辑的实现,既然业务逻辑无法避免又那么复杂,那么设计出合理的业务逻辑架构来加快开发效率就显得尤为重要。

本框架将业务逻辑独立一层,其核心继承关系如下图(图6-2)所示:

业务逻辑层类图

图6-2 业务逻层次图

如上图所示:首先定义了一个业务逻辑基类BaseBusiness < T >,该基类实现了常用的业务操作方法,其余所有业务处理类都需要继承自基类BaseBusiness < T >,其中泛型T为数据库实体,一般默认操作单张表,但在实际运用中连表操作十分的普遍,因此在BaseBusiness中提供了Service属性,该属性为IRepository类型,因此可以操作泛型接口,传入不同的实体类型即可对应到所需表的操作,故而支持联表操作,方便开发人员操作数据库。基类还提供了通用业务逻辑返回数据,Success和Error分别对应成功请求返回和失败请求返回,统一数据格式,方便前后端开发对接。

应用展示层 这层也可以称之为应用层,其余的层表现形式都是类库,而这一层负责具体项目应用的实施,比如可以使用控制台程序、Windows服务程序、WinForm程序、WCF程序等等,在本项目中使用了ASP.NET Core MVC网站项目负责具体功能的实现。

AOP(Aspect Oriented Programming)使用:AOP,即面向切片编程,利用AOP能够将系统各个部分进行隔离,从而降低模块之间的耦合度,提高程序可用性,同时提高开发效率。本框架中主要使用了以下AOP:

管理员登录校验CheckLoginAttribute:在后台管理系统中,管理员只有登录后才能够进行相关操作,一般通过Session来记录管理员登录信息,最简单直接就是在每一个请求中都需要判断一遍管理员是否登录,这无疑将会导致很多的重复代码,此时,通过将登陆校验作为一个特性,只需要在需要登录的控制器或方法上添加该特性即可完成管理员登录校验,这样就能够减少大量的重复代码,加快开发效率。

签名校验CheckSignAttribute:当后端接口需要给外部系统调用时,若不对接口访问进行限制,那么就会面临恶意请求攻击的风险,轻则影响系统性能,重则导致系统瘫痪,数据被恶意串改,此时,保证接口的安全性就十分关键。保证接口的安全性,主要就是按照一定的签名算法,对请求者传入的参数进行签名校验,只有通过才能够正常访问,原始做法就是在每个请求中去进行签名校验,这同样会导致大量的重复代码,这时通过引入签名校验特性,只需要在需要签名校验的控制器或方法中加入特性即可,使用简单方便,开发效率也高。

应用层还在视图中使用了通用布局模板,并统一了代码规范,再集成了JQuery以及一些其它常用的JS类库,以Layui为主要前端UI框架,界面风格统一,开发效率高。

使用教程 全局配置 在01.GoodERP.Util中的GlobalSwitch类中,设置了各个参数,其中RunModel需要重点关注一下,若RunModel==RunModel.LocalTest,则系统会直接跳过登录,默认使用Admin超级管理员登录,其它参数请看注释。

安装教程

系统安装说明 1.vc++运行时安装 http://www.ddooo.com/softdown/168263.htm

2.redis安装

直接用redis-server启动 也可以用nssm变为服务自动启动

3.mysql 8安装 解压缩版: 解压下载好的压缩包放到你想要放的目录:

用管理员打开CMD,切换到MySql的解压目录下的bin目录:

再输入命令mysqld --initialize --console来初始化数据库,并记录红色标注的字符,这是随机生成的密码:

输入mysqld -install将mysql安装为Windows的服务:

输入命令net start mysql或sc start mysql启动mysql服务

停止MySQL服务:net stop mysqld或sc stop mysqld 删除MySQL服务:sc delete mysqld或mysqld -remove(需先停止服务) 双击打开安装包,点击下一步

勾选我同意,点击下一步

选择安装路径后,点击下一步

点击下一步

点击下一步

点击安装

安装完成

Navicat for MySQL破解 注册机配置 1.Products选择“MySQL” 2.Porducts这里选择”Mysql“ 3.Languages选择“Simplified Chinese” 4.最后点击Pacth,这时候需要选择你的Navica15.exe,或者等待一到俩分钟它会弹出一个弹窗为止。

打开Navicat 15.x for MySQL软件,进行注册 点击注册机上的Generate生成许可证秘钥,如果未显示绿色对号,而是显示红叉,说明你的Products或者Languages选择错误,或者保留有之前注册的密钥未删除,需要到注册表中删除它。(找到 HKEY_CURRENT_USER\Software\PremiumSoft 这个路径下的 Navicat 的相关注册表,删除它。)

点击“激活”按钮,进行激活;然后点击“手动激活”;然后点击“Generate”,生成激活码,然后将激活码复制到框中点击激活按钮激活即可

然后点击激活 就激活成功 6.导入系统数据 使用Navicat 15.x for MySQL新建数据库 还原20231210135650.nb3 备份文件 7.安装崔佧智能ERP系统

解压门禁平台到安装文件夹 修改appsettings.json配置文件

"ProjectName": "鸿鹄技术", // 项目名称
"ProjectTitle": "智能制造系统", //title
"ProjectLogin1": "鸿鹄技术", //项目login
"ProjectLogin2": "智能制造ERP系统", //项目login
"DesktopUrl": "/WorkFlow/WorkFlow/pending", //首页  home/Desktop
"Company": "鸿鹄(深圳)创新技术有限公司",
"Telephone": "联系电话:",
"miit": "粤ICP备17108067号",
"IsJob": true,
"IsTcp": true,

"IsRedis": true,

修改数据库连接字符串 BaseDbMySql

通过GoodERP.Web文件启动ERP系统,也可通过nssm将ERP系统启动为服务

使用说明

培训提纲: 第1章 框架模块 1 框架主界面 1框架主菜单栏

2功能导航区

3公告区

4状态栏 2公司、单位、用户、角色管理 1添加公司、单位

2修改公司、单位

添加和修改时会检测树的是否有循环引用 3删除公司、单位

3用户管理 系统中获取当前用户 IOperator operater { get => AutofacHelper.GetScopeService(); } 或者 IOperator operater= AutofacHelper.GetScopeService();

UserId为系统生成的用户Id Property为用户的相关属性,部门,角色 Logged方法 判断当前是否有用户登录 Logout方法登出当前用户

Property属性中含有用户的基础属性用户名,姓名,部门Id,首页和默认语言等相关基础属性。还有角色列表,部门名等 1添加用户

用户名:登陆时所使用的账号 密码:添加用户时 不输入默认为123456 输入时即为输入值 姓名:用户姓名 角色:选择用户所属劫色 用户语言:选择用户所使用语言,一般选择中文即可 默认首页:默认为/ 即默认首页,司机或者其他特殊人员可以设置不同的默认页面 2修改用户

修改用户时不输入密码默认为原来的密码 4角色管理 1角色添加

2角色修改

3角色删除

5 模块(菜单)管理 1菜单添加、修改与删除 开发管理下【菜单管理】显示如下图 单击【添加】

FsNo 为菜单排序号 层级:ThirdMenu 菜单:临时勤务管理 图标:fa fa-circle-o 地址:~/Security/baseform/Index?id=&isview=false&TableName=bwb_cfg_tempduty 注:bwb_cfg_tempduty为表单配置管理里的表名称,根据实际名称配置 权限:bwb_cfg_tempduty.search 父级ID:日常管理(从下拉选择中选择) 其它项不用填写,单击【确定】按钮 显示列表中,单击【审核】按钮

审核通过后,单击【刷新菜单】

2操作(菜单)权限 菜单定义权限项,在下面的操作权限管理模块进行权限管理分配菜单权限 6操作权限管理模块 1操作权限添加、修改与删除 现阶段操作权限为文件添加

需要进入系统安装目录 wwwroot/Config路径 Permission为管理员的全部权限 UserPermission为其他账号的权限 以上两个为权限定义文件,分别定义对应模块的权限项

权限定义格式: 系统内权限判断: PermissionManage PermissionManage = new PermissionManage();//首先获取系统权限管理器,里面会自动根据相关用户加载对应的权限 var canManage = PermissionManage.OperatorHasPermissionValue("cbg_dispatch.manage");//然后用OperatorHasPermissionValue()方法获取对应的权限,权限字符串前半段为模块或者表名,后半段为权限项,返回值为bool类型,true代表当前用户有相应权限,false表示没有 var canadd = PermissionManage.OperatorHasPermissionValue("cbg_dispatch.add");//添加 7用户授权管理模块 1用户权限设置

2用户角色关联

添加和修改用户时可选择角色,角色可多选

8角色授权管理模块 1角色权限设置

第2章 系统配置

下拉配置 1、 系统所有界面表单都可以直接设置下拉、弹窗选择、多选下拉、上传文件等功能; 设置下拉先设置下拉的数据源。数据源表名为系统自动提取的业务单据类,数据源代码是数据值,数据源值是显示的数据内容。数据源条件,可以设备业务表单查询任意条件。

2、打开下拉配置菜单,如下图。 选择数据源表名,下拉字段,再选择设置好的下拉数据源,下拉数据的样式:1、下拉框,2、弹窗选择,3、多选下拉框,4、文件上传,6、可选可填,7、富文本框,8、多选框,9、按钮单选

3、其中数据源表名是业务表单对应的数据表实体。 为了方便查看使用,我们也可以在多语音配置表中即这些数据表实体名定义成中文显示。

5、如下图是上传文件的下拉数据源配置。

6、下图是人员照片的文件上传配置,数据源ID选择上传文件下拉数据源。

基础数据配置

基础数据配置:用来配置基础数据字典 主从表配置 1、系统也提供直接的主从表配置开发,如下图是主从表关系的配置。需要填写主表、细表完整路径(即细表的实体)、从表名称(用于在表单tab页上显示)、主表的主键、明细表与主表关联的外键等。

打印模板管理 多语言管理 设置系统支持的语言类型

语言内容管理

语言内容管理主要字段 语言:该字符值对应的语言 zh-CN中文 en为英文 字符代码:字符值的唯一标识 字符值:显示值

一般不用主动添加语言内容,在代码中用字符代码获取时 会自动创建 ITranslateService TranslateService = AutofacHelper.GetScopeService(); 获取翻译服务 string GetTranslate(string Language, string code, string def); TranslateService.GetTranslate("","System_Flash","刷新") 第一个参数为语言代码,为空默认当前用户默认语言,第二个参数为字符代码,第三个为默认字符值 返回值为配置的字符值,当字符值为空 则返回默认字符值

数据库连接管理 系统还支持多数据库连接的应用。可以在数据库连接管理中维护多个连接,在整个系统中,就可以分模块使用不同的系统。 . 代码生成 24、鸿鹄低代码最核心的功能是可以快速实现业务表单功能。用户可以打开代码生成,进入到如下图。下图是系统自动检测到系统的所有数据库表。勾选需要生成表单功能的数据库表。

25、点生成代码后,出现如下图界面。用户可以进一步确定生成选项。默认新的程序功能都是需要生成全部的,再填写生成区域。生成区域会作为实体类名存在于系统中。

打印机配置管理

配置打印机 用来配置系统使用的打印机 打印机需要配置在服务器端才能使用 配合打印模板 进行单据的打印 在清洁化项目上未使用 后台任务管理

后台任务管理:管理quartz模块中正在允许的计划任务,能手动执行任务,暂停任务,恢复任务

计划任务管理:配置需要允许的计划任务,在系统启动时会自动将计划任务加载到quartz模块 并显示到后台任务管理模块 也可以用添加任务按钮实时添加到quartz模块中

任务类 表示计划任务的完整类名 任务类须继承IJob

复杂查询 ///

/// 获取数据列表 /// /// 分页参数 /// 查询参数树 /// //新版复杂查询 public ActionResult GetDataListByComplexQuery(Pagination pagination, ComplexQuery ComplexQuerys, string cdate = "all") { if (ComplexQuerys.IsNullOrEmpty()) { ComplexQuerys = new ComplexQuery(); } ComplexQuery _ComplexQuerys = new ComplexQuery(); //表示该组的查询条件为并 _ComplexQuerys.condition = "AND"; if (operater.Property.UserName == "Admin" || operater.Property.RoleNameList.Contains("全部派单数据查看")) { //当用户为Admin或者有全部派单数据查询角色时 可以显示所有部门数据 ComplexQuery _ComplexQuerys_Rule = new ComplexQuery(); //获取当前数据(通行日期从两天前开始的数据) if (cdate == "current") { _ComplexQuerys_Rule = new ComplexQuery(); //查询条件对应的字段 _ComplexQuerys_Rule.field = "passagedate"; //查询条件的操作条件: //相等 //public const string EQUAL = "equal"; //大于 //public const string GREATER = "greater"; //小于 //public const string LESS = "less"; //大于或者等于 //public const string GREATER_OR_EQUAL = "greater_or_equal"; //小于或者等于 //public const string LESS_OR_EQUAL = "less_or_equal"; //不等于 //public const string NOT_EQUAL = "not_equal"; //包含 字符串 //public const string CONTAINS = "contains"; //以。。。开始 字符串 //public const string BEGIN = "begin"; //以。。。结束 字符串 //public const string END = "end"; //不包含 字符串 //public const string NOT_CONTAINS = "not_contains"; //不包含 字符串 //public const string BECONTAINS = "becontains"; //逗号分割的包含 字符串 //public const string LISTCONTAINS = "listcontains"; //不在。。之中 //public const string NOT_IN = "not_in"; //在。。之中 //public const string IN = "in"; //在。。之间 //public const string BETWEEN = "between"; //不在。。之间 //public const string NOT_BETWEEN = "not_between"; //为空 //public const string IS_EMPTY = "is_empty"; //为NULL //public const string IS_NULL = "is_null"; //不为空 //public const string IS_NOT_EMPTY = "is_not_empty"; //不为NULL //public const string IS_NOT_NULL = "is_not_null"; //条件关系词 _ComplexQuerys_Rule.@operator = SearchHelper.GREATER_OR_EQUAL; //条件值 _ComplexQuerys_Rule.value = DateTime.Now.Date.AddDays(-2); _ComplexQuerys.rules.Add(_ComplexQuerys_Rule); } _ComplexQuerys.rules.Add(ComplexQuerys); //查询并翻译 /* Pagination 分页条件 主要字段: sortName 排序字段名 sortOrder 排序方式 desc asc pageNumber 页数 pageSize 页面数据条数 */ var dataList1 = _cbg_dispatchBus.GetDataListByComplexQuery(pagination, _ComplexQuerys); return DataTable_Bootstrap(dataList1, pagination); } else { ComplexQuery _ComplexQuerys_Rule = new ComplexQuery(); if (cdate == "current") { _ComplexQuerys_Rule = new ComplexQuery(); _ComplexQuerys_Rule.field = "passagedate"; _ComplexQuerys_Rule.@operator = "greater_or_equal"; _ComplexQuerys_Rule.value = DateTime.Now.Date.AddDays(-2); _ComplexQuerys.rules.Add(_ComplexQuerys_Rule); } //当用户没有权限时 可以显示所属部门数据 _ComplexQuerys_Rule = new ComplexQuery(); _ComplexQuerys_Rule.field = "depart"; _ComplexQuerys_Rule.@operator = "equal"; _ComplexQuerys_Rule.value = operater.Property.DepartmentId.IsNullOrEmpty() ? "9999999999" : operater.Property.DepartmentId; _ComplexQuerys.rules.Add(_ComplexQuerys_Rule);

            //_ComplexQuerys_Rule = new ComplexQuery();
            //_ComplexQuerys_Rule.field = "passagedate";
            //_ComplexQuerys_Rule.@operator = "greater_or_equal";
            //_ComplexQuerys_Rule.value = DateTime.Now.Date.AddDays(-1);
            //_ComplexQuerys.rules.Add(_ComplexQuerys_Rule);


            _ComplexQuerys.rules.Add(ComplexQuerys);
            var dataList = _cbg_dispatchBus.GetDataListByComplexQuery(pagination, _ComplexQuerys);
            return DataTable_Bootstrap(dataList, pagination);
        }
    }

SignalR消息推送

公众号等其他消息推送

appid 为需要推送消息的appid wxappid 为需要推送消息的wxappid 如果需要跳转小程序(公众号消息) pagepath 为跳转小程序的页面 userId 消息接受人的用户Id templeteId 模板Id messageobj 消息 //发送消息内容给消息处理系统 推送消息 PushMessageHelper.PushMessagePonit(weiXinApp, "DispatchReverseMesssage_Starter", "派单驳回消息推送_发起人");

远程Business QueryableWeb远程服务 用来与门禁系统进行通讯获取门禁系统的相关信息 QueryableWeb(string _Url, string _key, string _CacheKey, TimeSpan _span, bool _IsCache = false); _Url 门禁系统Api服务地址 _key JWTKey当Api需要权限时填写 JWTHelper.GetJWTKey();//获取当前用户的JWTKey _CacheKey 缓存Key _span 缓存刷新时间 _IsCache 是否需要缓存

系统初始化 添加数据库配置

JWT配置

Swagger文档生成配置

数据库日志配置

Redis缓存和Session配置

SignalR配置和数据库用户缓存配置

定时任务和雪花Id生成器配置

微信配置

Autofac服务注册

第3章 清洁化运输模块 注册用户管理 清洁化司机注册 cbg_register 字段名 中文描述 字段类型 长度 默认值 Id   varchar 50   username 用户名 varchar 50   pwd 密码 varchar 10   truck_ph 车牌号 varchar 50   ph_color 车牌颜色 varchar 50   IsTruckRegister 是否注册 varchar 50 '0' qwdw 服务单位 varchar 50   man 姓名 varchar 50   card 身份证号 varchar 50   tel 手机号 varchar 50   note 备注 varchar 200   IsDelete 删除标识 varchar 50 '1' Remark 描述 varchar 200   StatusFlag 使用状态 varchar 1   CreateDate 创建日期 datetime 0   CreateOperator 创建人 varchar 20   ModifyDate 修改日期 datetime 0   ModifyOperator 修改人 varchar 20  

注册用户管理 用来记录司机注册时填写的注册信息,以及记录当前司机的车辆注册状态 业务流程:

特殊字段: IsTruckRegister=‘0’表示当前注册车辆已经提交等待审核 IsTruckRegister=‘1’表示当前注册车辆已经审核通过 IsTruckRegister=‘2’表示当前注册车辆被驳回 控制器: cbg_registerController.cs 页面: 1.司机注册填写界面 cbg_register/ FormReg.cshtml 2.司机注册列表 cbg_register/ Index.cshtml 3.司机注册明细界面 cbg_register/ Form.cshtml

单位派单 表名 单位派单 cbg_dispatch     字段名 中文描述 字段类型 长度 默认值 Id 主键 varchar 50   isjl 是否计量 varchar 10   state 预约状态 varchar 10 '0' truck_ph 车牌号码 varchar 50   ph_color 车牌颜色 varchar 50   passagedate 通行日期 datetime 0   goodstype 物资种类一级 varchar 50   goodsname 物资名称 varchar 50   descsize 规格型号 varchar 300   quantity 数量 decimal 18   unit 计量单位 varchar 50   indoor 进门岗 varchar 50   outdoor 出门岗 varchar 50   goodsdirection 物资运输方向 varchar 50   goodsplace 运送地点 varchar 100   depart 派单单位 varchar 50   dispathpeople 派单人员 varchar 50   dispathtime 派单时间 datetime 0   note 备注 varchar 300   forwarding_unit 发货单位 varchar 100   receiving_unit 收货单位 varchar 255   gross 毛重 decimal 18   tare 皮重 decimal 18   suttle 净重 decimal 18   gross_dtime 毛重时间 datetime 0   tare_dtime 皮重时间 datetime 0   weightcname 称名 varchar 50   planbillcode 计划单号 varchar 50   contractcode 合同号 varchar 50   truck_xh 原单号 varchar 50   invalidflag 作废标识 varchar 1 '0' IsDelete 删除标识 varchar 1 '1' sources 来源钢源 13钢联 14 清洁化运输平台 varchar 10 '0' Remark 描述 varchar 200   StatusFlag 使用状态 varchar 1   CreateDate 创建日期 datetime 0   CreateOperator 创建人 varchar 20   ModifyDate 修改日期 datetime 0   ModifyOperator 修改人 varchar 20   realindoor 真实进门岗 varchar 50   realoutdoor 真实出门岗 varchar 50   InOut 进出状态 varchar 50   doorintime 进门岗时间 datetime 0   doorouttime 出门岗时间 datetime 0  

单位派单: 有二级单位发起人发起派单填写相关信息,二级单位审核人审核,然后司机接单 在司机进出门岗后 门禁系统会调用接口 将进出时间和进出门岗回写。 业务流程:

特殊字段: Isjl 是否计量 是否需要计量中心计量数据 state 单据接单状态 0表示未接单 1表示已接单 业务代码: 新增和修改: 1.    2.var action = new Action(() =>//事务action   3.                {     4.                    AjaxResult s = new AjaxResult();   5.                        theData.truck_ph = theData.truck_ph.Replace(" ", "").Trim().ToUpper();//处理车牌大小写空格   6.                        ISpecialNoDispatchTruckInfoBusiness SpecialtruckInfoBusiness = AutofacHelper.GetScopeService();//获取特殊的不允许派单车辆信息服务   7.                        var Specialtruck = SpecialtruckInfoBusiness.GetIQueryable().Where(t=>t.truck_ph==theData.truck_ph&&t.ph_color==theData.ph_color).ToList().FirstOrDefault();   8.                        //检测到车辆不允许派单 则抛出错误   9.if (!Specialtruck.IsNullOrEmpty())   10.                        {   11.                            throw new Exception(theData.truck_ph + "车辆疫情管控 无法派单");   12.                        }   13.                        //检测是否计量字段 不允许为空   14.                        if (theData.isjl.IsNullOrEmpty())   15.                        {   16.                            throw new Exception(theData.truck_ph + "是否计量过磅不能为空");   17.                        }   18.//检测品名 不允许为空   19.                        if (theData.goodsname.IsNullOrEmpty())   20.                        {   21.                            throw new Exception(theData.truck_ph + "物资名称不能为空");   22.                        }   23.//检测是否计量的字段值   24.                        if (theData.isjl != "1" && theData.isjl != "0")   25.                        {   26.                            throw new Exception(theData.truck_ph + "是否计量过磅数据错误");   27.                        }   28.IDoorBusiness _DoorBusiness = AutofacHelper.GetScopeService();//获取门岗配置服务   29.//检测进出门岗值不在配置的门岗之中 则返回错误   30.                        if (!_DoorBusiness.GetIQueryableWeb().Where($@"filedcode = ""{theData.indoor}""").ToList().Any() || !_DoorBusiness.GetIQueryableWeb().Where($@"filedcode = ""{theData.outdoor}""").ToList().Any())   31.                        {   32.                            throw new Exception(theData.truck_ph + "门岗信息错误请从模板中选择或者重新导入模板  不能自行填写");   33.                        }   34.//特殊规则:热电门岗不能申请黄牌车   35.                        if ((theData.indoor == "door3" && theData.ph_color == "1") || (theData.outdoor == "door3" && theData.ph_color == "1"))   36.                        {   37.                            throw new Exception(theData.truck_ph + "热电门岗不能申请黄牌车");   38.                        }   39.                        //IRetentionTruckBusiness retentionTruckBusiness = AutofacHelper.GetScopeService();   40.                        //if (!retentionTruckBusiness.GetIQueryable().Where(t => t.truck_ph == theData.truck_ph && t.ph_color == theData.ph_color && t.IsLock == "1").ToList().Any())   41.                        //{   42.                        //    throw new Exception(theData.truck_ph + "滞留超时已经锁定无法派单");   43.                        //}   44.   45.                        //IRetentionLockBusiness retentionLockBusiness = AutofacHelper.GetScopeService();   46.                        //if (!retentionLockBusiness.GetIQueryable().Where(t => t.truck_ph == theData.truck_ph && t.ph_color == theData.ph_color).ToList().Any())   47.                        //{   48.                        //    throw new Exception(theData.truck_ph + "车辆滞留超时清理出厂后短期锁定无法派单");   49.                        //}   50.//检测物资运输方向值 主要针对Excel导入   51.                        IGoodsDirectionBusiness pLATE_COLORBusiness = AutofacHelper.GetScopeService();   52.                        var zltype = pLATE_COLORBusiness.GetIQueryableAll().ToList();   53.                        if (!zltype.Where(t=>t.filedcode== theData.goodsdirection).Any())   54.                        {   55.                            throw new Exception(theData.truck_ph + "物资运输方向错误请从模板中选择或者重新导入模板  不能自行填写");   56.                        }   57.//检测物资种类是否为空   58.                        if (theData.goodstype.IsNullOrEmpty())   59.                        {   60.                            throw new Exception(theData.truck_ph + "物资种类不能为空");   61.                        }   62.//检测物资种类编号   63.                        IGoodsTypeBusiness goodsTypeBusiness = AutofacHelper.GetScopeService();   64.                        if (!goodsTypeBusiness.GetIQueryableWeb().Where($@"excode = ""{theData.goodstype}""").ToList().Any())   65.                        {   66.                            throw new Exception(theData.truck_ph + "物资种类" + theData.goodstype + "信息错误,请填写正确的编号不要填写中文");   67.                        }   68.//检测车辆是否在清洁化平台注册   69.                        Id_truck_tempBusiness id_Truck_TempBusiness = AutofacHelper.GetScopeService<Id_truck_tempBusiness>();   70.                        var truck1 = id_Truck_TempBusiness.GetIQueryable().Where(t=>t.truck_ph== theData.truck_ph&&t.ph_color==theData.ph_color&&t.StatusFlag=="1").FirstOrDefault();   71.                        if (truck1.IsNullOrEmpty())   72.                        {   73.                            throw new Exception(theData.truck_ph + "车辆信息不存在或者未审核无法派单");   74.                        }   75.//检测车辆信息是否存在于门禁平台   76.                        ITruckInfoBusiness truckInfoBusiness = AutofacHelper.GetScopeService();   77.                        var truck = truckInfoBusiness.GetIQueryableWeb().Where($@"truck_ph=""{theData.truck_ph}"" and ph_color=""{theData.ph_color}"" ").ToList().FirstOrDefault();   78.                        if (truck.IsNullOrEmpty())   79.                        {   80.                            throw new Exception(theData.truck_ph+"车辆信息不存在无法派单");   81.                        }   82.//检测是否为增加数据 Id为空时为修改   83.if (theData.Id.IsNullOrEmpty())   84.                    {   85.                        theData.Id = IdHelper.GetId();//IdHelper.GetId()获取雪花Id   86.                        theData.depart = operater.Property.DepartmentId; //获取用户所属部门   87.                        theData.dispathpeople = operater.Property.RealName; //获取用户姓名   88.                        theData.dispathtime = DateTime.Now; //获取派单时间   89.                        theData.sources = "14";//设置派单来源 清洁化平台为14 钢联物流平台为13   90.                        s = _cbg_dispatchBus.AddData(theData);   91.                    }   92.                    else   93.                    {   94.                        s = _cbg_dispatchBus.UpdateData(theData);   95.                    }                       96.                });   97.                //执行事务获取数据库更新结果   98.                var res =_cbg_dispatchBus.RunTransaction(action);   99.                if (!res.Item1) return Error(res.Item2.Message);   100.                return Success();  

司机接单:

  1. public AjaxResult AddInOutOrder(cbg_dispatch dispatch)   2.        {   3.            //检测单据是否空   4.            if (dispatch.IsNullOrEmpty())   5.            {   6.                return AjaxHelper.Error("单据未审核或已作废");   7.            }   8.            //获取健康码服务   9.            Icbg_healthcodeBusiness icbg_HealthcodeBusiness = AutofacHelper.GetScopeService<Icbg_healthcodeBusiness>();   10.            //获取已经审核未失效的健康码   11.            var healthcoderes=icbg_HealthcodeBusiness.GetApproveHealthCode(operater.Property.Id, dispatch.truck_ph,dispatch.ph_color);   12.            //var _healthcode = icbg_HealthcodeBusiness.GetIQueryable().Where(t => t.user == operater.Property.Id && t.cdate >= DateTime.Now.AddHours(-72) && t.StatusFlag == "1").OrderByDescending(t => t.cdate).FirstOrDefault();   13.            //if (!_healthcode.IsNullOrEmpty())   14.            //{   15.            //    IInOutEvidenceBusiness inOutEvidenceBusiness = AutofacHelper.GetScopeService();   16.            //    if (!inOutEvidenceBusiness.GetIQueryable().Where(t => t.doortime >= _healthcode.CreateDate && t.truck_ph == dispatch.truck_ph && t.ph_color == dispatch.ph_color && t.state == "1" && t.InOut == "out").ToList().Any())   17.            //    {   18.            //        healthcode = healthcode;   19.            //    }   20.            //}   21.//不存在已审核的疫情防控信息时 推送错误消息   22.            if (!healthcoderes.Success)   23.            {   24.                try   25.                {   26.       //不存在已审核的疫情防控信息时 推送错误消息   27.                    IHubContext hub = AutofacHelper.GetService<IHubContext>();   28.                    var s = MessageHub.OnlineUser;   29.                    var clientsId = s.Where(t => t.UserID == operater.UserId).Select(t => t.ConnectionId).ToList();   30.                    if (clientsId.Count > 0)   31.                    {   32.                        hub.Clients.Clients(clientsId).SendAsync("HealthCode" + operater.UserId, new { Data = "疫情防控信息未上传或者审核未通过,请刷新页面;" });   33.                    }   34.                }   35.                catch (Exception ex)   36.                {   37.                    LogHelper.WriteLog_LocalTxt(ExceptionHelper.GetExceptionAllMsg(ex));   38.                }   39.                return AjaxHelper.Error("疫情防控信息未上传或者审核未通过 无法接单,请刷新页面");   40.            }   41.            //获取进出单据服务   42.            Icbg_driverinoutBusiness icbg_DriverinoutBusiness = AutofacHelper.GetScopeService<Icbg_driverinoutBusiness>();   43.//获取当前的进出单据   44.            var driver = GetCurInOutOrder();   45.//如果存在当前的进出单据,刷新单据状态 然后重新检测 如果依然存在则返回当前有未完成的进出单,请先完成进出单,然后接单   46.            if (driver.Success)   47.            {   48.                GetCurInOutOrderDetail1();   49.                driver= GetCurInOutOrder();   50.                if (driver.Success)   51.                {   52.                    return AjaxHelper.Error("当前有未完成的进出单,请先完成进出单,然后接单");   53.                }   54.            }   55.//检测派单单据状态   56.            if (dispatch.state != "0")   57.            {   58.                return AjaxHelper.Error("单据已接单已作废");   59.            }   60.//获取门禁Api服务地址   61.            var ApiUrl = configuration.GetValue("ApiUrl");   62.            var res = icbg_DriverinoutBusiness.RunTransaction(() =>   63.            {   64.                //ICapPublisher _capBus = AutofacHelper.GetScopeService();   65.                cbg_driverinout _Driverinout = new cbg_driverinout();   66.                _Driverinout.Id = IdHelper.GetId();   67.                _Driverinout.indispatch = dispatch.Id;   68.                _Driverinout.outdispatch = dispatch.Id;   69.                _Driverinout.username = operater.UserId;   70.                _Driverinout.drivername = operater.Property.RealName;   71.                _Driverinout.passdate = dispatch.passagedate;   72.                _Driverinout.truck_ph = dispatch.truck_ph;   73.                _Driverinout.ph_color = dispatch.ph_color;   74.                icbg_DriverinoutBusiness.AddData(_Driverinout);   75.                icbg_DriverinoutBusiness.ApproveData(new List { _Driverinout.Id});   76.                icbg_DispatchBusiness.UpdateWhere_Sql(t => t.Id == dispatch.Id, ("state", "1"), ("Remark", $@"{DateTime.Now} {operater.Property.UserName} {operater.Property.RealName} 接单"));   77.                Dictionary<string, object> keyValuePairs = new Dictionary<string, object>();   78.                _Driverinout.username = operater.Property.Telephone.IsNullOrEmpty() ? operater.Property.UserName : operater.Property.Telephone;   79.                keyValuePairs.Add("dispatch", new { dispatch = dispatch, driverinout = _Driverinout });   80.                //_capBus.Publish("bgmj/DriverInoutEvidence/AddDriverInoutEvidence", keyValuePairs);   81.                var res=HttpHelper.PostDataJWT(ApiUrl + "/bgmj/DriverInoutEvidence/AddDriverInoutEvidence", JWTHelper.GetJWTKey(), keyValuePairs,null,ContentType.Json);   82.                AjaxResult s = res.ToObject();   83.                if (!s.Success)   84.                {   85.                    throw new Exception(s.Msg);   86.                }   87.            });   88.            if (res.Success)   89.            {   90.                return AjaxHelper.Success();   91.            }   92.            else   93.            {   94.                return AjaxHelper.Error(res.ex.Message);   95.            }   96.        }  

车辆注册审核

车辆注册审核二级单位设置 设置司机可选的二级单位 审核通过的单位为司机所选的服务单位 原来的设计是在这里设置审核人和发起人 但是设置方式过于繁琐 现在有角色和用户所属部门来控制

驳回记录 司机车辆审核审核人驳回以及司机撤回原因和记录

作废单据审核 司机提交单据作废申请 二级单位在本页面审核 然后就可以作废旧单据 然后新接单 审核时需要填写作废原因

进出单据 根据车牌号和颜色查询当前车辆的有效的进出单据 数据通过API接口从门禁系统查询

计量数据补全 补全未获取到的计量数据

审核记录 车辆注册信息的审核记录

车辆信息查询 通过Api查询门禁系统的车辆信息

历史进出单据查询 根据车牌号和颜色查询当前车辆的历史进出单据 数据通过API接口从门禁系统查询

非道路移动机械管理 添加管理非道路移动机械

通知公告管理 公告栏

管理公告栏内容

滞留申请 查看车辆厂内滞留申请

健康码行程码审核 审核运输车辆和司机疫情防控信息

双击打开详细页面查看司机疫情防控信息:

健康码行程码审核查询 因为司机上传疫情防控信息只有司机选择的服务单位才能看到 如果司机一天需要给不同的单位运输货品 可以在此页面用司机身份证号查询当天司机上传的疫情防控信息和审核状态 双击页面也能打开详情信息

场所码 各单位添加场所码下载场所码界面

添加场所码:

下载场所码:

第4章 业务组成(以派单为例) 总体结构

一个业务表生成的代码由以下 Controller:控制器和前端进行交互的逻辑 View:前端代码

Business:和数据库交互的业务代码 IBusiness: Business的接口 Entity:实体代码

1.控制器 Controller

Area表示控制器所属的域 Route表示该控制器的路由 控制器继承BaseMvcContrller 该基控制器会加入登录验证和JWT接口机制

注入实体的Buiness 和系统数据转换帮助类

视图主要时定义该控制器拥有的页面 页面定义在对应的Views中

Index为主页 生成代码为主页面 带有增删改查 分页的列表显示界面 一般页面都要使用系统数据转换帮助类 public virtual ViewResult View(); public virtual ViewResult View(string viewName, object model); public virtual ViewResult View(object model); public virtual ViewResult View(string viewName); 页面方法 需要返回View(“页面名”) 如果为空则默认为方法名 当第一个参数为其他类型时 自动赋值给Model参数可以在页面上使用

return View(theData);

return View("FormHealthCode", healthcode);

司机主页面例子: //司机主页面 public ActionResult IndexTel() { //获取司机注册信息 var res = IsTruckReg(); if (res.Success) { //检测到用户属于司机 string truck_ph = ""; string ph_color = ""; //获取司机信息 cbg_register ress = (cbg_register)res.Data; if (!ress.IsNullOrEmpty()) { truck_ph = ress.truck_ph; ph_color = ress.ph_color; } //设置车辆信息 ViewData["listHelper"] = listHelper; ViewData["truck_ph"] = truck_ph; ViewData["ph_color"] = ph_color; //获取基础配置服务 Ibase_configBusiness ibase_Config = AutofacHelper.GetScopeService<Ibase_configBusiness>(); //获取疫情防控信息是否需要上传的配置 var isyq = ibase_Config.GetIQueryable().Where(t => t.type == "isyqmode").FirstOrDefault(); if (!isyq.IsNullOrEmpty() && isyq.code == "1") { //获取疫情防控信息上传服务 Icbg_healthcodeBusiness icbg_HealthcodeBusiness = AutofacHelper.GetScopeService<Icbg_healthcodeBusiness>(); //获取当前用户的疫情防控信息 var healthcoderes = icbg_HealthcodeBusiness.GetHealthCode(operater.Property.Id, truck_ph, ph_color); if (!healthcoderes.Success) { //疫情防控信息不存在时 生成疫情防控信息 var healthcode = new cbg_healthcode(); healthcode.Id = IdHelper.GetId(); healthcode.truck_ph = truck_ph; healthcode.ph_color = ph_color; healthcode.StatusFlag = ""; //获取用户已经上传过的人脸照片 var healthcodephoto = icbg_HealthcodeBusiness.GetIQueryable().Where(t => t.user == operater.Property.Id && t.userphoto != "" && t.userphoto != null).OrderByDescending(t => t.cdate).FirstOrDefault(); if (!healthcodephoto.IsNullOrEmpty()) { healthcode.userphoto = healthcodephoto.userphoto; } //获取用户车辆注册默认部门 if (!ress.IsNullOrEmpty()) { var truckinfo = _cbg_dispatchBus.GetIQueryable<d_truck_temp>().Where(t => t.registerid == operater.Property.UserName && t.truck_ph == truck_ph && t.ph_color == ph_color && t.StatusFlag == "1").FirstOrDefault(); if (!truckinfo.IsNullOrEmpty()) { healthcode.depart = truckinfo.qwdw; } } //获取用户姓名 healthcode.username = operater.Property.RealName; //获取用户Id healthcode.user = operater.Property.Id; //获取用户身份证号 healthcode.usersfzh = ress?.card; ViewData["isview"] = false; //跳转到疫情信息填写界面等待司机填写上传 return View("FormHealthCode", healthcode); } else { //如果疫情信息存在 并且未审核 则跳转到疫情信息显示界面等待审核 var healthcode = (cbg_healthcode)healthcoderes.Data; if (healthcode.StatusFlag != "1") { if (healthcode.StatusFlag == "2" || healthcode.StatusFlag.IsNullOrEmpty()) { ViewData["isview"] = false; } else { ViewData["isview"] = true; } return View("FormHealthCode", healthcode); } } } //InOutOrderAction inOutOrder = new InOutOrderAction(); //var resss = inOutOrder.GetCurInOutOrderDetailGLWL(truck_ph, ph_color); //获取可以单进单出的特殊车辆 ISpecialTruckInfoBusiness truckInfoBusiness = AutofacHelper.GetScopeService(); var truck = truckInfoBusiness.GetIQueryableWeb().Where($@"truck_ph=""{truck_ph}"" and ph_color=""{ph_color}"" ").ToList().FirstOrDefault(); if (truck.IsNullOrEmpty()) { //如果不是特殊车辆则跳转接单界面 return View(); } else { //特殊车辆则跳转特殊车辆接单界面:有单进单出派单页面 return View("IndexTelHuoche"); } } else { //如果未绑定车辆 cbg_register ress = (cbg_register)res.Data; if (ress.IsNullOrEmpty()) return Error("账号非司机注册");

            // ITruckInfoBusiness truckInfoBusiness = AutofacHelper.GetScopeService<ITruckInfoBusiness>();
            //var truck = truckInfoBusiness.GetIQueryableWeb().Where($@"truck_ph=""{ress.truck_ph}"" and ph_color=""{ress.ph_color}"" ").ToList().FirstOrDefault();
            //获取用户已经填写未审核的车辆信息
            d_truck_temp temp = _cbg_dispatchBus.GetIQueryable<d_truck_temp>().Where(t => t.registerid == ress.username && t.StatusFlag != "1").FirstOrDefault();
            //获取用户注册时填写的车辆的已经通过审核的注册信息(用来填充车辆的相关信息 简化填写 为一辆车注册多个司机服务)
            d_truck_temp temp1 = _cbg_dispatchBus.GetIQueryable<d_truck_temp>().Where(t => t.truck_ph == ress.truck_ph && t.ph_color == ress.ph_color && t.StatusFlag == "1").FirstOrDefault();
            //判断当前用户是否填写过车辆信息
            if (temp.IsNullOrEmpty())
            {

                //判断当前车辆是否有已经通过审核的车辆信息
                if (!temp1.IsNullOrEmpty())
                {
                    //如果有则把车辆信息填充到当前用户的车辆信息中
                    temp = temp1;
                    temp.Id = "";
                    temp.registerid = ress.username;
                    temp.StatusFlag = "";
                }
                else
                {
                    //如果没有则检查门禁系统是否有该车辆的信息,将信息填充到当前用户的车辆信息中
                    ITruckInfoBusiness truckInfoBusiness = AutofacHelper.GetScopeService<ITruckInfoBusiness>();
                    var truck = truckInfoBusiness.GetIQueryableWeb().Where($@"truck_ph=""{ress.truck_ph}"" and ph_color=""{ress.ph_color}"" ").ToList().FirstOrDefault();
                    if (!truck.IsNullOrEmpty())
                    {
                        temp = InsertTempLog(truck);
                    }
                }
                //如果已经获取到有效的车辆信息,则将当前用户的的信息填充进驾驶员的信息
                if (!temp.IsNullOrEmpty())
                {
                    if (!ress.IsNullOrEmpty())
                    {
                        temp.driver_id = ress.man;
                        temp.driver_sfzh = ress.card;
                        temp.driver_telephone = ress.tel;
                    }
                }
            }
            else
            {
                //如果已经获取到有效的车辆信息,则将当前用户的的信息填充进驾驶员的信息
                temp.driver_id = ress.man;
                temp.driver_sfzh = ress.card;
                temp.driver_telephone = ress.tel;
            }
            //如果未获取到有效的车辆信息则生成新的车辆信息
            if (temp.IsNullOrEmpty())
            {
                temp = new d_truck_temp();
                if (!ress.IsNullOrEmpty())
                {
                    temp.truck_ph = ress.truck_ph;
                    temp.ph_color = ress.ph_color;
                    temp.driver_id = ress.man;
                    temp.driver_sfzh = ress.card;
                    temp.registerid = ress.username;
                    temp.driver_telephone = ress.tel;
                }
            }
            ViewData["listHelper"] = listHelper;
            //车辆信息可以编辑
            if (ress.IsTruckRegister == "0")
            {
                ViewData["isview"] = false;
            }
            //车辆信息已经提交等待审核不可编辑
            //IsTruckRegister = "1" 则表示车辆已经通过审核可以接单了
            if (ress.IsTruckRegister == "2")
            {
                ViewData["isview"] = true;
            }
            return View("FormRegCarinfo", temp);
        }
    }

业务方法:

业务逻辑方法 用来获取相关数据和更新相关数据 复杂查询: ///

/// 获取数据列表 /// /// 分页参数 /// 查询参数树 /// //新版复杂查询 public ActionResult GetDataListByComplexQuery(Pagination pagination, ComplexQuery ComplexQuerys, string cdate = "all") { if (ComplexQuerys.IsNullOrEmpty()) { ComplexQuerys = new ComplexQuery(); } ComplexQuery _ComplexQuerys = new ComplexQuery(); //表示该组的查询条件为并 _ComplexQuerys.condition = "AND"; if (operater.Property.UserName == "Admin" || operater.Property.RoleNameList.Contains("全部派单数据查看")) { //当用户为Admin或者有全部派单数据查询角色时 可以显示所有部门数据 ComplexQuery _ComplexQuerys_Rule = new ComplexQuery(); //获取当前数据(通行日期从两天前开始的数据) if (cdate == "current") { _ComplexQuerys_Rule = new ComplexQuery(); //查询条件对应的字段 _ComplexQuerys_Rule.field = "passagedate"; //查询条件的操作条件: //相等 //public const string EQUAL = "equal"; //大于 //public const string GREATER = "greater"; //小于 //public const string LESS = "less"; //大于或者等于 //public const string GREATER_OR_EQUAL = "greater_or_equal"; //小于或者等于 //public const string LESS_OR_EQUAL = "less_or_equal"; //不等于 //public const string NOT_EQUAL = "not_equal"; //包含 字符串 //public const string CONTAINS = "contains"; //以。。。开始 字符串 //public const string BEGIN = "begin"; //以。。。结束 字符串 //public const string END = "end"; //不包含 字符串 //public const string NOT_CONTAINS = "not_contains"; //不包含 字符串 //public const string BECONTAINS = "becontains"; //逗号分割的包含 字符串 //public const string LISTCONTAINS = "listcontains"; //不在。。之中 //public const string NOT_IN = "not_in"; //在。。之中 //public const string IN = "in"; //在。。之间 //public const string BETWEEN = "between"; //不在。。之间 //public const string NOT_BETWEEN = "not_between"; //为空 //public const string IS_EMPTY = "is_empty"; //为NULL //public const string IS_NULL = "is_null"; //不为空 //public const string IS_NOT_EMPTY = "is_not_empty"; //不为NULL //public const string IS_NOT_NULL = "is_not_null"; //条件关系词 _ComplexQuerys_Rule.@operator = SearchHelper.GREATER_OR_EQUAL; //条件值 _ComplexQuerys_Rule.value = DateTime.Now.Date.AddDays(-2); _ComplexQuerys.rules.Add(_ComplexQuerys_Rule); } _ComplexQuerys.rules.Add(ComplexQuerys); //查询并翻译 /* Pagination 分页条件 主要字段: sortName 排序字段名 sortOrder 排序方式 desc asc pageNumber 页数 pageSize 页面数据条数 */ var dataList1 = _cbg_dispatchBus.GetDataListByComplexQuery(pagination, _ComplexQuerys); return DataTable_Bootstrap(dataList1, pagination); } else { ComplexQuery _ComplexQuerys_Rule = new ComplexQuery(); if (cdate == "current") { _ComplexQuerys_Rule = new ComplexQuery(); _ComplexQuerys_Rule.field = "passagedate"; _ComplexQuerys_Rule.@operator = "greater_or_equal"; _ComplexQuerys_Rule.value = DateTime.Now.Date.AddDays(-2); _ComplexQuerys.rules.Add(_ComplexQuerys_Rule); } //当用户没有权限时 可以显示所属部门数据 _ComplexQuerys_Rule = new ComplexQuery(); _ComplexQuerys_Rule.field = "depart"; _ComplexQuerys_Rule.@operator = "equal"; _ComplexQuerys_Rule.value = operater.Property.DepartmentId.IsNullOrEmpty() ? "9999999999" : operater.Property.DepartmentId; _ComplexQuerys.rules.Add(_ComplexQuerys_Rule);

            //_ComplexQuerys_Rule = new ComplexQuery();
            //_ComplexQuerys_Rule.field = "passagedate";
            //_ComplexQuerys_Rule.@operator = "greater_or_equal";
            //_ComplexQuerys_Rule.value = DateTime.Now.Date.AddDays(-1);
            //_ComplexQuerys.rules.Add(_ComplexQuerys_Rule);


            _ComplexQuerys.rules.Add(ComplexQuerys);
            var dataList = _cbg_dispatchBus.GetDataListByComplexQuery(pagination, _ComplexQuerys);
            return DataTable_Bootstrap(dataList, pagination);
        }
    }

2.页面 Index页面代码解释:

Layout = "~/Views/Shared/_Layout_List.cshtml"; //设置页面框架 PermissionManage PermissionManage = new PermissionManage(); //获取权限管理器 Var manageSysPermission = PermissionManage.OperatorHasPermissionValue("cbg_dispatch.manageSysPermission"); //根据权限代码获取权限

根据获取的权限 设置当前用户可使用的操作

获取设置的扩展字段简单查询条件

复杂查询初始化

页面公告

分组按钮组

初始化按钮组条件 并且绑定按钮触发执行的逻辑 点击按钮时改变条件变量 并触发列表刷新

将用户权限传输给前端js 来控制按钮是否显示

图片相册模式显示代码

表格初始化参数配置

url:获取表格数据的接口 idField:表格主键 method: 接口调用方式 get post contentType:返回内容类型 clickToSelect:点击选中行 pagination:是否分页 sortName:排序字段名 sortOrder:排序类型 desc倒序 asc 正序 sidePagination:server表示服务器分页 height:表格高度 为了自适应页面大小

pageList:分页大小选择列表 showRefresh:显示刷新功能按钮

showColumns:显示字段隐藏设置功能按钮

showToggle:显示模式切换功能按钮

表格字段设置 checkbox表示多选框 操作字段里面是操作按钮 用权限和字段值来判断按钮是否显示 使用状态为数据的状态:1 审核通过 2 驳回 3 未处理

数据字段和扩展字段显示
你可以用formatter:来控制字段的显示方式 比如图片等

获取的数据显示之前的预处理 这里为将字段的实际设置为字段的显示值:翻译在后台系统数据转换帮助类中生成带__Name的字段为显示值

查询条件组装

var result = $('#builder').queryBuilder('getRules'); 获取复杂查询条件

打开明细表单

操作数据

Form页面代码解释: 获取数据,设置显示模板,设置显示模式

字段显示配置获取: base_selectresource_data dataselecttruck_ph = dataHelper.GetDataUrlAll("CleanBG", "cbg_dispatch", "truck_ph"); 根据域,表名,字段名获取字段的下拉配置 然后根据配置的类型不同 进行不同显示模式 1、下拉框,2、弹窗选择,3、多选下拉框,4、文件上传,6、可选可填,7、富文本框,8、多选框

扩展字段显示

获取字段联动配置

字段转换为json字符串传给js变量; isview控制字段是否可编辑

初始化treeSelect数据 elem:字段对应的Id data:数据获取的接口 type:接口的访问类型 get post placeholder:显示的占位字符 click:点击之后的操作 给字段赋值 success:加载完成后初始化选项

表单校验和提交

3.Business 初始化相关变量

简单查询 pagination:为分页参数 searchInfos:为查询条件列表 var q = GetIQueryable(); 获取查询器 searchInfos = listHelper.GetDataKeys(typeof(cbg_dispatch).FullName, searchInfos);将下拉配置的条件转换成Id条件 让可以用显示值搜索

SearchHelper.SearchInfoToWhere<cbg_dispatch>(ref param, ref keys, searchInfos);将查询条件列表 转换为Where条件 if (!param.IsNullOrEmpty() && !keys.IsNullOrEmpty()) q = q.Where(param, keys.ToArray()); 将查询条件传入查询器 listHelper.DataTableSelect<cbg_dispatch>(q.GetPagination(pagination).ToDataTable()); 传入分页条件并使用系统数据操作帮助类 BaseDataHelper 获取和组装字段的显示值

复杂查询: ComplexQuerys:复杂查询条件 处理复杂查询条件不同 其他操作方式和简单查询类似

简单查询导出数据 List infos = dbHelper.GetDbTableInfo(EnumHelper.GetTableName(typeof(cbg_dispatch)));根据实体类型获取表名 组装用来装导出数据的DataTable

根据Id获取实体数据

添加数据

更新数据

删除数据

审核数据

反审核数据:

4.实体

参与贡献

鸿鹄(深圳)创新技术有限公司

QQ群:491338424(技术交流、安装配置交流)

群主小程序客服

特技

输入图片说明

nuget地址:http://www.gooderp.net:8000/v3/index.json

MIT License Copyright (c) 2023 184027749 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

鸿鹄创新长期专注于企业资源计划ERP、智能制造、系统集成等企业信息化相关领域,为客户提供深入和长期的顾问咨询、客户化定制开发及配套的系统服务。经过多年研发,打造了gooderp低代码平台,平台简单易用,集成工作流和智能硬件接口,可以快速为企业量身定制各种管理系统,并根据中小企业需求实现了ERP系统,可以自由定义适配多个行业的中小企业。 展开 收起
MIT
取消

发行版 (1)

全部

贡献者

全部

近期动态

加载更多
不能加载更多了
C#
1
https://gitee.com/gooderp2020/gooderp-code.git
git@gitee.com:gooderp2020/gooderp-code.git
gooderp2020
gooderp-code
gooderp低代码框架erp.mes.oa流程系统
master

搜索帮助