@TOC
springboot307基于Vue的MES生产制造执行系统
第1章 绪论
1.1 选题动因
到现在为止,互联网已经进入了千家万户,最普通的平民百姓也有属于自己的智能设备,计算机各种技术的储备也是相当的丰富,并且实现也是没有难度,各行各业,包括一些个人,也积极拥抱互联网时代的到来,也可以说是互联网时代的到来把人们都给包在互联网之中。从刚开始的政府办公,国家企业的开头使用,到如今的老百姓都能用上,别说那些普通企业了。计算机就是有这样的魅力,互联网被称为浪潮不是浪得虚名的。采用计算机技术,开发一些软件,实现软件所在的目的,这是一个常理,这个基础的常理缩短了地域之间的联系,提高了地域竞争水准,减低了人力成本和数据存储成本。本课题研究的MES生产制造执行系统,也是采用了计算机技术,该系统能够提高产品生产制造信息数据的检索速度,使用起来非常的方便。
1.2 目的和意义
在MES生产制造执行系统实际操作中,使用者会发现使用起来相当的方便,并且对数据的管理者来讲,也能及时的获得自己想要的数据,对整个数据的所有者能提供强大的帮助,MES生产制造执行系统从操作者的角度出发,不管是在数据的接收以及传递,以及处理结果,都有一个很明显的要求,对有效数据的处理,并且形成集合,并且对有效数据集合进行固定化处理,可以得到更有效的数据,有了MES生产制造执行系统,让管理层不至于把大量的人力和财力资源消耗在数据处理整合方面,完全可以让不知疲倦的计算机来进行,不仅投入减低,并且产出也不少。互联网时代就是如此,顺之者昌,响应互联网时代,不至于说可以乘风破浪,起码可以降低直接淘汰出局的几率。MES生产制造执行系统的出现是顺应时代的。
1.3 论文结构安排
MES生产制造执行系统的论文结构将从6个章节进行阐述。具体结构安排如下:
第1章:本章节对本课题的选题动因,本课题的研究目的和意义进行说明。
第2章:本章节对本课题需要运用的环境和技术进行说明。
第3章:本章节对本课题性能,功能进行分析,对系统开发的经济,技术等条件是否可行进行说明。
第4章:本章节对本课题具体的功能进行设计,同时也对系统的数据库进行E-R图设计以及数据表设计。
第5章:本章节对实现的功能的运行效果图进行展示,同时对系统的功能进行说明。
第6章:本章节对系统功能上的测试进行说明,对测试的结果进行分析。
第2章 开发环境与技术
MES生产制造执行系统需要提前对功能进行调查分析,并且根据分析结果进行技术上的辩证,可以选择更合理的开发技术以及开发工具。
2.1 Tomcat 简介
只要学习Java Web项目就不得不学习Tomcat。Tomcat是一种免费的开源的一种Java Web项目的容器,完美继承了 Apache服务器的特性,并且里面添加可以自动化运行的Java Web组件,让Java Web项目可以完全的运行到Tomcat里面。对于特大型项目来讲,直接用Tomcat会造成启动变慢,处理有限等,所以对项目进行了前后端分离技术,但是对于需要称不上特大型的项目来讲,普通的大中型项目用Tomcat作为Java Web项目的运行容器是完全够资格的。最重要的是Tomcat完全跟着Java EE,每一次Java EE的升级,Tomcat都会有着对应的版本出现,版本更新速度是非常快的。更新速度快,代表着有技术方面的支持,值得用户使用的,让用户更加信赖Tomcat产品。
2.2 Eclipse简介
Eclipse这款开发工具最最重要的特点就是免费,不管是用来开发任何的东西,哪怕用来教学或者是生产,只要是能带了商业价值的生产都可以免费使用,这一点对于IDEA或者MyEclipse来讲,是非常的具有前瞻性的。免费的也许有很多不足,但是就是因为免费,所以很多人愿意贡献自己的力量,让这款免费的工具可以拥有更多的插件,用起来更加的舒心。可以这么说,Eclipse就是Java语言开发行业的鼻祖,只要是学过Java的人,对Eclipse没有不熟悉的。Eclipse操作起来非常的方便,可以不用安装,直接解压了就可以使用,并且可以在不同的操作系统上面都可以安装到对应的版本。Eclipse是真的不要钱,免费,下载就能用,这么多年以来长期占领着Java开发市场的半壁江山。Eclipse可以在官网上进行捐款,捐款可以支持Eclipse进一步发展,也可以不捐款直接使用,一切随心,不会强求。Eclipse真的是一款良心Java生产工具。
2.3 Navicat简介
Navicat是一款管理数据库的软件。众所周知,所有的数据库只是以特定的存放格式进行存放的,访问也需要特定的接口以及语句进行访问。如果访问数据库都用各种命令,不仅仅是开发效率上会大大的降低,并且看起来也不舒服,对于某些数据或者数据库来讲这样并不友好,如何对数据库进行友好的访问到现在为止,不同的数据库厂商都推出了适合自己数据库的管理工具,但是有一点就是,数据库厂商推出之后,只要能用就行,并没有符合人体工程学,所有的数据库厂商推出的数据库管理工具都是免费的,所以并没有对于数据库管理工具进行过多的优化,用起来相当的不友好,并且各个数据库工具是不能通用的,这一点数据库厂商肯定不会去做匹配其他数据库的管理工具,所以Navicat就应运而生,可以采用Navicat管理各种各样的数据库,可以同时访问各种数据库并且通过不同的连接进行访问,还可以访问不同电脑的数据库,页面操作简单,美观大方,用起来很好用,并且占用电脑资源很小,很适合作为替代其他数据库厂商推出的数据库管理工具使用。
2.4 Vue框架
Vue框架因为是纯JavaScript开发的模式,只需要通过浏览器就可以进行解析,不需要增加服务端的处理压力。Vue框架最典型的就是渐进式显示模式,举一个小小的例子,如果一个商店一些商品的库存或者价格不变,会急速的显示,如果一处地方进行变换,那么只要引用到这个变化数据的所有数据都会自动变化,让数据显示的实时性大大的增加,让用户使用起来更加的友好。对开发者而言,Vue框架非常好理解,编写起来能极大的减少DOM的相关操作,让页面渲染更加的有层次。当前端不在需要关注一些不必要的操作的时候,能让程序开发人员的注意力都能集中到业务逻辑方面,这样从这一个方面又能极大的提高了开发效率。所以Vue框架这个火爆是有原因的。
第3章 系统分析
通过对系统的功能进行具体分析,可以参考已经发表过的具有参考价值的文章作为对比,这样能把功能分析的很透彻,并且也会因为功能的分析而对性能也有大致的了解,并且可以预测性能,实现性能分析的结果。
3.1 可行性分析
系统的设计必须符合正常逻辑,所以设计之处,也需要从其他方面来论证其可行性。
3.1.1 经济可行性
开发MES生产制造执行系统,存在经济上面的支持,必须经济上的支持才可以有序进行,比如是否需要额外购买开发工具,购买开发电脑,或者从开发技术上是否是免费开源,达到的效果上面是否支出与收入不匹配,这些都需要进行分析。由于开发本系统,开发技术开源且稳定,电脑用正在使用的电脑就能满足,不需要太多的经济支出就可以达到目的,经济可行性通过。
3.1.2 技术可行性
MES生产制造执行系统软件主要用到的一些工具,而这些工具正好在学校就使用过,并且网上有很多免费的并且符合的开发工具,技术方面也学过,并且有图书馆的资源和网络资源可以充分利用。所以在技术角度上面来分析是可以的。
3.1.3 操作可行性
操作方面分为开发过程,实现过程,项目具体操作流程。这些因为都学过,并且有其他的项目流程作为参考。总体实现一般就是用户的登录相关,权限分配,基础数据的变更体现。让不同的角色有不同的操作界面,符合正确角色定位,使用者在操作上面并不会感觉到很突兀,影响操作流程。所以操作方面是可以的。
通过以上不同角度的分析,最后论证分析了可行性是没有问题的,完全可以进行后续步骤。
3.2 系统流程分析
操作逻辑是一个可以用画图工具展示的,因为数据在录入过程中的不可见,只能看到返回结果,所以把流程画成图可以更好的理解其中的顺序。
在系统的各项操作中,其他的录入环节,会对操作者具体操作的每条信息都会提出验证要求,比如不能为空,只能是汉字,以及其他的要求等,这些都在前端需要编写清楚,达到友好提示的目的,有效的帮助操作人员理解操作。具体数据的流程如下面的图所示。当操作员输入信息后,点击提交后台就会接收操作员提交的信息,并且提前编写好的逻辑会继续验证,如果数据合格就存入到数据库里并且返回成功提示,这样一个录入环节就达到了设计要求。
图3.1 添加信息流程图
有时候录入的一些数据可能需要修改,修改就是纠正之前的操作,所以修改数据必须是先把想要修改的数据从数据库里获取出来,然后在这个之上进行修改,修改数据也有相应的操作流程。
图3.2 修改信息流程图
数据的查询是在任何程序上都是一个常规的操作,面对的数据量不一样,想要获取想要的数据时间也不一样,都是尽快的获取自己想要的结果,所以数据查询就需要有个查询条件作为查询关键词,这样可以更好的获取符合关键词的数据。
图3.3 查询信息流程图
3.3 系统性能分析
关于MES生产制造执行系统从性能需求方面来分析,主要从五个角度分析。五个角度分别从设计的实用性,设计的操作性,设计的安全性,设计的适应性和维护性这五个角度来进行分析。
首先分析第一点,设计的实用性。本设计的目的就是让管理员可以综合的处理各种基础信息,并且有相应的权限来进行操作,达到数据同步,集中管理的目的,并且可以让用户处理用户相关信息,符合设计的既定目标,达到使用效果。
其次分析第二点,设计的操作性。开发出来的系统必须有操作性,如果操作起来丢三落四,出现各种不符合流程的操作,那么就是不符合设计规则的,设计的操作性必须符合人体工程学使用原则,从上到下,从左到右,让操作起来更加的有逻辑性,不需要不符合逻辑的页面数据体验和操作流程,让设计的操作性体现出来,看到操作界面就会有相应的下一步理解。
再次是安全性,虽然从任何角度来讲,安全性应该放到第一位,但是有些时候安全性是在数据量大并且数据重要的前提下才会对数据的安全性来进行设计,正常的软件使用过程只要数据设计合理,并且目标单一,让黑客不屑于或者付出不成正比的情况下,安全性自然可以稍微降低一点,毕竟面对的使用群体决定了安全性的强度。本设计主要是从毕业设计的角度出发,增加一点数据校验的安全性就行,没必要设置硬件防火墙之类的资源,所以安全性上面也是符合的。
再次是适应性。适应性主要是面对各种平台的操作系统,目前本设计的开发可以使用本人电脑进行开发,服务器可以架设到任何地方,并且有对应的服务器软件版本。而用户方面只需要能上网,有最新版本的浏览器进行支持即可,所以适应性是相当不错的。
最后是分析维护性。这一点只需要维护服务端代码即可,每次服务端代码维护都可以先把服务器停止,然后在开发电脑上进行测试,最后测试无误再在服务器上进行部署,维护性并不会增加多少成本。
3.4 系统功能分析
当设计人员通过参考各种文献以及其他类似项目的调研后,就会对项目具体的功能进行分析,这样有的放矢可以更快的设计程序的功能。
MES生产制造执行系统的操作者有管理员,分析的管理员功能将使用用例图进行展示。图3.4展示了管理员用例图。管理员管理工序信息,管理工艺线路,管理物料信息,管理客户信息,管理销售订单,管理产品信息,管理生产计划等。
图3.4 管理员用例图
MES生产制造执行系统的操作者有员工,分析的员工的功能将使用用例图进行展示。图3.5展示了员工用例图。员工查看工序信息,查看工艺线路,查看物料信息,查看产品信息,查看产品生产计划,管理客户信息,管理销售订单等。
图3.5 员工用例图
第4章 系统设计
在系统设计环境,业务的处理逻辑和数据的设计逻辑虽然是重中之重,但是这些都是用户看不见摸不着的,用户也只是能看到部署好的项目运行起来的结果,所以用户对界面布局以及界面功能比较看重。所以说,如今只要是开发网站不仅仅是需要懂一点页面设计就行,也需要懂得UI设计的人群。传统的网页设计其实就是换几个颜色,放几张图片,然后来充实操作页面,让操作页面不至于太单调,但是互联网发展至今,开发也越来越精细化,用户越来越挑剔,还用凑合方式来进行程序开发,已经是属于落后的状态了。
4.1 布局设计原则
布局不是传统的把页面分分类,输入和显示页面,调整调整间距这些笼统的说法了,布局设计也是有一定的原则的。
首先,布局一定要清晰合理。布局的清晰不是说图片清晰或者文字清晰,而是说用户在使用过程中,看到导航的布局,就能明白所有功能模块都可以在导航里寻找,打开一个页面,就能知道重要与不重要的资料,必须与不必须的填写,甚至是输入的格式是什么规格,都可以让用户使用的时候一目了然。因为界面是有限的,所以说布局是相当重要的一点设计原则。
其次,布局的体现要符合大众审美,比如说导航,尽量都是网页的上方或者左侧。如果把导航放到网页下方或者右方,这些代码都是可以实现,但是不符合正常人的思维定向。现代人的读写习惯都是从上而下,从左到右的阅读方式,人们身体和心灵已经习惯了这种方式,如果布局到其他方向首先用户会感到新颖,但是却不会买账,因为操作几遍后就会不习惯。
最后,布局也要考虑这个软件是用来做什么的,常用这个软件的人员的年龄划分,性别划分,以及职业划分。划分了使用人群,就可以对背景进行调色填充,如果是长时间用电脑的人群尽量设计的有护眼功能,不至于看一会眼睛就受不了,尽量要区分长时间使用和短时间使用的背景,这一点很重要。
综上所述,系统设计需要考虑方方面面,布局设计也是需要精细化考虑,系统设计需要考虑太多,但是实现却不能弄得操作上太复杂,系统设计尽量的要满足用户需要,提高用户满意度。
4.2 功能结构设计
在基于系统功能分析的基础之上,开始对系统的详细功能进行设计,最终将使用结构图的形式对设计的结果进行展示。
管理员具备的详细功能将参照最终的设计结果,即图4.1所示的管理员功能结构图。其中管理员管理工序信息,管理工艺线路,管理物料信息,管理客户信息,管理销售订单,管理产品信息,管理生产计划等。
图4.1 管理员功能结构图
员工具备的详细功能将参照最终的设计结果,即图4.2所示的员工功能结构图。其中员工查看工序信息,查看工艺线路,查看物料信息,查看产品信息,查看产品生产计划,管理客户信息,管理销售订单等。
图4.2 员工功能结构图
4.3 数据库设计
数据库的选用方面肯定要选一个市场反应比较好,性价比比较高的数据库,不能凭空想象数据库,要结合程序设计的需求来选择对应的数据库。目前来讲,市面上常用的关系型数据库足够达到需求。
4.3.1 数据库E-R图设计
想好更好的设计出数据库使用效果,那么就要对数据的存放格式以及存放关系作出调查和梳理,所以通过分析E-R图之间的数据实体关系是最好不过的。而设计数据库E-R图是有下面几点好处:
第一点:数据的冗余是一件很恐怖的事情,所以要对有些数据进行冗余筛选;
第二点:防止内存溢出,数据量太大,需要提前做好预测并且设定好规则;
第三点:数据库一定要完整,非完整数据也只是数据垃圾而已,没有任何作用;
第四点:提高数据检索性能;
这节主要是描述对系统的E-R模型的设计,数据存储格式的判断,实现的方法,用户的需要,这些都要统一,不能想当然。并且各个模型中间的关系尤其要突出。
(1)把生产计划具备的属性通过属性图进行展示,绘制的属性图见图4.4。
图4.4 生产计划实体属性图
(2)把销售订单具备的属性通过属性图进行展示,绘制的属性图见图4.5。
图4.5 销售订单实体属性图
(3)把员工具备的属性通过属性图进行展示,绘制的属性图见图4.6。
图4.6 员工实体属性图
(4)把管理员具备的属性通过属性图进行展示,绘制的属性图见图4.7。
图4.7 管理员实体属性图
(5)上述实体间关系见图4.8。
图4.8 实体间关系E-R图
4.3.2 数据库表结构设计
数据库设计必须符合规范,那就是三大范式,这样能确保数据的合理:
第一范式:保证表之间的字段关系不存在混淆的描述,必须描述准确,并且单一,不能分解;
第二范式:在上述的满足条件上,主键的设计必须要在固定的列上,不能忽前忽后;
第三范式:继续满足上个条件,保证每个字段都可以根据主键获取到,并且在一个数据表里体现。
所以说,三个范式是一脉相承的,不是说零碎的,从第一个范式上就会发现,第一个永远是基础,后面的设定就是后者的实现必须在前面范式的基础之上的要求,这些设计可以最大化的减少数据冗余,提高数据库运行效率。
表4.1 部门信息表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | bigint(20) | 否 |
addtime | 创建时间 | timestamp | 否 |
bumenmingcheng | 部门名称 | varchar(200) | 是 |
bumenfuzeren | 部门负责人 | varchar(200) | 是 |
lianxidianhua | 联系电话 | varchar(200) | 是 |
bangongquyu | 办公区域 | varchar(200) | 是 |
表4.2 产品信息表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | bigint(20) | 否 |
addtime | 创建时间 | timestamp | 否 |
chanpinbianhao | 产品编号 | varchar(200) | 是 |
chanpinmingcheng | 产品名称 | varchar(200) | 是 |
chanpinleixing | 产品类型 | varchar(200) | 是 |
shuliang | 数量 | int(11) | 是 |
jiage | 价格 | int(11) | 是 |
chanpinshuoming | 产品说明 | longtext | 是 |
chanpintese | 产品特色 | varchar(200) | 是 |
chanpinguige | 产品规格 | date | 是 |
shiyongfanwei | 适用范围 | varchar(200) | 是 |
表4.3 工序信息表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | bigint(20) | 否 |
addtime | 创建时间 | timestamp | 否 |
gongxumingcheng | 工序名称 | varchar(200) | 是 |
gongxuleixing | 工序类型 | varchar(200) | 是 |
gongxushizhang | 工序时长 | varchar(200) | 是 |
caozuoliucheng | 操作流程 | longtext | 是 |
gongxufujian | 工序附件 | varchar(200) | 是 |
shiyongjiqi | 适用机器 | varchar(200) | 是 |
zhuyishixiang | 注意事项 | varchar(200) | 是 |
表4.4 工艺线路表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | bigint(20) | 否 |
addtime | 创建时间 | timestamp | 否 |
chanpinbianhao | 产品编号 | varchar(200) | 否 |
chanpinmingcheng | 产品名称 | varchar(200) | 否 |
chanpinleixing | 产品类型 | varchar(200) | 是 |
gongyimingcheng | 工艺名称 | varchar(200) | 否 |
jiagongyuanliao | 加工原料 | longtext | 是 |
gongyiliucheng | 工艺流程 | longtext | 是 |
gongzuoyuanli | 工作原理 | longtext | 是 |
表4.5 客户信息表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | bigint(20) | 否 |
addtime | 创建时间 | timestamp | 否 |
kehumingcheng | 客户名称 | varchar(200) | 是 |
kehulaiyuan | 客户来源 | varchar(200) | 是 |
xingye | 行业 | varchar(200) | 是 |
guojiadiqu | 国家地区 | varchar(200) | 是 |
dianhua | 电话 | varchar(200) | 是 |
dizhi | 地址 | varchar(200) | 是 |
kehudengji | 客户等级 | varchar(200) | 是 |
yuangonggonghao | 员工工号 | varchar(200) | 是 |
表4.6 生产计划表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | bigint(20) | 否 |
addtime | 创建时间 | timestamp | 否 |
chanpinbianhao | 产品编号 | varchar(200) | 否 |
chanpinmingcheng | 产品名称 | varchar(200) | 是 |
chanpinleixing | 产品类型 | varchar(200) | 是 |
shengchanshuliang | 生产数量 | int(11) | 否 |
chanpintese | 产品特色 | varchar(200) | 是 |
chanpinguige | 产品规格 | varchar(200) | 是 |
shiyongfanwei | 适用范围 | varchar(200) | 是 |
shengchanjihua | 生产计划 | longtext | 是 |
gongyimingcheng | 工艺名称 | varchar(200) | 是 |
gongxumingcheng | 工序名称 | varchar(200) | 是 |
dengjishijian | 登记时间 | varchar(200) | 是 |
yuangonggonghao | 员工工号 | varchar(200) | 是 |
yuangongxingming | 员工姓名 | varchar(200) | 是 |
表4.7 管理员表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | bigint(20) | 否 |
username | 用户名 | varchar(100) | 否 |
password | 密码 | varchar(100) | 否 |
role | 角色 | varchar(100) | 是 |
addtime | 新增时间 | timestamp | 否 |
表4.8 物料信息表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | bigint(20) | 否 |
addtime | 创建时间 | timestamp | 否 |
wuliaobianhao | 物料编号 | varchar(200) | 是 |
wuliaomingcheng | 物料名称 | varchar(200) | 否 |
wuliaoleixing | 物料类型 | varchar(200) | 否 |
wuliaoguige | 物料规格 | varchar(200) | 是 |
tupian | 图片 | varchar(200) | 是 |
shuliang | 数量 | int(11) | 是 |
jiage | 价格 | float | 是 |
wuliaoxiangqing | 物料详情 | longtext | 是 |
表4.9 销售订单表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | bigint(20) | 否 |
addtime | 创建时间 | timestamp | 否 |
xiaoshoudanhao | 销售单号 | varchar(200) | 是 |
chanpinbianhao | 产品编号 | varchar(200) | 是 |
chanpinmingcheng | 产品名称 | varchar(200) | 是 |
chanpinleixing | 产品类型 | varchar(200) | 是 |
jiage | 价格 | int(11) | 是 |
xiaoshoushuliang | 销售数量 | int(11) | 是 |
zongxiaoshoue | 总销售额 | int(11) | 是 |
xiaoshoushijian | 销售时间 | datetime | 是 |
beizhu | 备注 | longtext | 是 |
kehumingcheng | 客户名称 | varchar(200) | 是 |
dianhua | 电话 | varchar(200) | 是 |
dizhi | 地址 | varchar(200) | 是 |
yuangonggonghao | 员工工号 | varchar(200) | 是 |
yuangongxingming | 员工姓名 | varchar(200) | 是 |
表4.10 员工表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | bigint(20) | 否 |
addtime | 创建时间 | timestamp | 否 |
yuangonggonghao | 员工工号 | varchar(200) | 否 |
mima | 密码 | varchar(200) | 否 |
yuangongxingming | 员工姓名 | varchar(200) | 否 |
xingbie | 性别 | varchar(200) | 是 |
bumen | 部门 | varchar(200) | 是 |
zhiwei | 职位 | varchar(200) | 是 |
ruzhishijian | 入职时间 | date | 是 |
lianxifangshi | 联系方式 | varchar(200) | 是 |
youxiang | 邮箱 | varchar(200) | 是 |
shenfenzheng | 身份证 | varchar(200) | 是 |
第5章 系统实现
下面主要是对系统实现的功能进行描述,一般在系统实现阶段只算是一个粗略的功能实现,可能符合开发人员的设计预期,但是对于具体使用者来讲还是需要其他人进行发现的,所以这个环节是很有必要进行描述的。
5.1 管理员功能实现
5.1.1 工艺线路管理
实现工艺线路管理功能,其界面运行的效果图见图5.1。在该界面,管理员修改,删除,查询工艺线路信息,对新的工艺线路信息进行添加等。工艺线路信息包括产品名称,工艺名称,产品编号,产品类型等信息。
图5.1 工艺线路管理界面
5.1.2 生产计划管理
实现生产计划管理功能,其界面运行的效果图见图5.2。在该界面,管理员更改生产计划信息,包括产品名称,生产数量,产品特色,产品规格,员工姓名,工艺名称等信息,管理员在生产计划管理界面新增生产计划,查询生产计划信息等。
图5.2 生产计划管理界面
5.1.3 生产计划统计报表
实现生产计划统计报表功能,其界面运行的效果图见图5.3。在该界面,管理员查看各个产品的生产计划信息,每个产品都设置有生产数量信息。
图5.3 生产计划统计报表界面
5.1.4 销售订单统计报表
实现销售订单统计报表功能,其界面运行的效果图见图5.4。在该界面,管理员查看各个产品对应的销售数量信息。销售订单统计报表是以柱状图的形式展示统计结果,非常直观地表达出统计的数据。
图5.4 销售订单统计报表界面
5.1.5 物料信息管理
实现物料信息管理功能,其界面运行的效果图见图5.5。在该界面,管理员把物料信息通过文件的形式进行导出,同时,管理员可以新增物料信息,对物料的名称,物料规格,数量,价格等信息进行查看,修改,查询,删除等。
图5.5 物料信息管理界面
5.2 员工功能实现
5.2.1 客户信息管理
实现客户信息管理功能,其界面运行的效果图见图5.6。在该界面,员工主要是添加客户,对客户的行业,国家地区,地址,客户等级,客户来源,客户名称等信息进行修改,查询等,可以查看客户统计报表信息。
图5.6 客户信息管理界面
5.2.2 客户信息统计报表
实现客户信息统计报表功能,其界面运行的效果图见图5.7。在该界面,主要是统计员工的所属行业信息,统计信息是通过饼图的方式进行显示。
图5.7 客户信息统计报表界面
5.2.3 销售订单管理
实现销售订单管理功能,其界面运行的效果图见图5.8。在该界面,员工新增产品销售订单,对销售订单的价格,销售数量,总销售额,客户名称等信息进行修改,查询等,员工也能查看销售订单的统计报表信息。
图5.8 销售订单管理界面
5.2.4 工序信息查看
实现工序信息查看功能,其界面运行的效果图见图5.9。在该界面,员工下载工序附件,查看产品工序时长,工序名称,工序类型等信息,可以通过工序类型或工序名称查询工序信息等。
图5.9 工序信息查看界面
InterceptorConfig.java
package com.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import com.interceptor.AuthorizationInterceptor;
@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport{
@Bean
public AuthorizationInterceptor getAuthorizationInterceptor() {
return new AuthorizationInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(getAuthorizationInterceptor()).addPathPatterns("/**").excludePathPatterns("/static/**");
super.addInterceptors(registry);
}
/**
* springboot 2.0配置WebMvcConfigurationSupport之后,会导致默认配置被覆盖,要访问静态资源需要重写addResourceHandlers方法
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/resources/")
.addResourceLocations("classpath:/static/")
.addResourceLocations("classpath:/admin/")
.addResourceLocations("classpath:/front/")
.addResourceLocations("classpath:/public/");
super.addResourceHandlers(registry);
}
}
KehuxinxiController.java
package com.controller;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.utils.ValidatorUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.annotation.IgnoreAuth;
import com.entity.KehuxinxiEntity;
import com.entity.view.KehuxinxiView;
import com.service.KehuxinxiService;
import com.service.TokenService;
import com.utils.PageUtils;
import com.utils.R;
import com.utils.MD5Util;
import com.utils.MPUtil;
import com.utils.CommonUtil;
import java.io.IOException;
/**
* 客户信息
* 后端接口
* @author
* @email
* @date 2022-04-04 11:25:38
*/
@RestController
@RequestMapping("/kehuxinxi")
public class KehuxinxiController {
@Autowired
private KehuxinxiService kehuxinxiService;
/**
* 后端列表
*/
@RequestMapping("/page")
public R page(@RequestParam Map<String, Object> params,KehuxinxiEntity kehuxinxi,
HttpServletRequest request){
String tableName = request.getSession().getAttribute("tableName").toString();
if(tableName.equals("yuangong")) {
kehuxinxi.setYuangonggonghao((String)request.getSession().getAttribute("username"));
}
EntityWrapper<KehuxinxiEntity> ew = new EntityWrapper<KehuxinxiEntity>();
PageUtils page = kehuxinxiService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, kehuxinxi), params), params));
return R.ok().put("data", page);
}
/**
* 前端列表
*/
@IgnoreAuth
@RequestMapping("/list")
public R list(@RequestParam Map<String, Object> params,KehuxinxiEntity kehuxinxi,
HttpServletRequest request){
EntityWrapper<KehuxinxiEntity> ew = new EntityWrapper<KehuxinxiEntity>();
PageUtils page = kehuxinxiService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, kehuxinxi), params), params));
return R.ok().put("data", page);
}
/**
* 列表
*/
@RequestMapping("/lists")
public R list( KehuxinxiEntity kehuxinxi){
EntityWrapper<KehuxinxiEntity> ew = new EntityWrapper<KehuxinxiEntity>();
ew.allEq(MPUtil.allEQMapPre( kehuxinxi, "kehuxinxi"));
return R.ok().put("data", kehuxinxiService.selectListView(ew));
}
/**
* 查询
*/
@RequestMapping("/query")
public R query(KehuxinxiEntity kehuxinxi){
EntityWrapper< KehuxinxiEntity> ew = new EntityWrapper< KehuxinxiEntity>();
ew.allEq(MPUtil.allEQMapPre( kehuxinxi, "kehuxinxi"));
KehuxinxiView kehuxinxiView = kehuxinxiService.selectView(ew);
return R.ok("查询客户信息成功").put("data", kehuxinxiView);
}
/**
* 后端详情
*/
@RequestMapping("/info/{id}")
public R info(@PathVariable("id") Long id){
KehuxinxiEntity kehuxinxi = kehuxinxiService.selectById(id);
return R.ok().put("data", kehuxinxi);
}
/**
* 前端详情
*/
@IgnoreAuth
@RequestMapping("/detail/{id}")
public R detail(@PathVariable("id") Long id){
KehuxinxiEntity kehuxinxi = kehuxinxiService.selectById(id);
return R.ok().put("data", kehuxinxi);
}
/**
* 后端保存
*/
@RequestMapping("/save")
public R save(@RequestBody KehuxinxiEntity kehuxinxi, HttpServletRequest request){
kehuxinxi.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
//ValidatorUtils.validateEntity(kehuxinxi);
kehuxinxiService.insert(kehuxinxi);
return R.ok();
}
/**
* 前端保存
*/
@RequestMapping("/add")
public R add(@RequestBody KehuxinxiEntity kehuxinxi, HttpServletRequest request){
kehuxinxi.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
//ValidatorUtils.validateEntity(kehuxinxi);
kehuxinxiService.insert(kehuxinxi);
return R.ok();
}
/**
* 修改
*/
@RequestMapping("/update")
public R update(@RequestBody KehuxinxiEntity kehuxinxi, HttpServletRequest request){
//ValidatorUtils.validateEntity(kehuxinxi);
kehuxinxiService.updateById(kehuxinxi);//全部更新
return R.ok();
}
/**
* 删除
*/
@RequestMapping("/delete")
public R delete(@RequestBody Long[] ids){
kehuxinxiService.deleteBatchIds(Arrays.asList(ids));
return R.ok();
}
/**
* 提醒接口
*/
@RequestMapping("/remind/{columnName}/{type}")
public R remindCount(@PathVariable("columnName") String columnName, HttpServletRequest request,
@PathVariable("type") String type,@RequestParam Map<String, Object> map) {
map.put("column", columnName);
map.put("type", type);
if(type.equals("2")) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar c = Calendar.getInstance();
Date remindStartDate = null;
Date remindEndDate = null;
if(map.get("remindstart")!=null) {
Integer remindStart = Integer.parseInt(map.get("remindstart").toString());
c.setTime(new Date());
c.add(Calendar.DAY_OF_MONTH,remindStart);
remindStartDate = c.getTime();
map.put("remindstart", sdf.format(remindStartDate));
}
if(map.get("remindend")!=null) {
Integer remindEnd = Integer.parseInt(map.get("remindend").toString());
c.setTime(new Date());
c.add(Calendar.DAY_OF_MONTH,remindEnd);
remindEndDate = c.getTime();
map.put("remindend", sdf.format(remindEndDate));
}
}
Wrapper<KehuxinxiEntity> wrapper = new EntityWrapper<KehuxinxiEntity>();
if(map.get("remindstart")!=null) {
wrapper.ge(columnName, map.get("remindstart"));
}
if(map.get("remindend")!=null) {
wrapper.le(columnName, map.get("remindend"));
}
String tableName = request.getSession().getAttribute("tableName").toString();
if(tableName.equals("yuangong")) {
wrapper.eq("yuangonggonghao", (String)request.getSession().getAttribute("username"));
}
int count = kehuxinxiService.selectCount(wrapper);
return R.ok().put("count", count);
}
/**
* (按值统计)
*/
@RequestMapping("/value/{xColumnName}/{yColumnName}")
public R value(@PathVariable("yColumnName") String yColumnName, @PathVariable("xColumnName") String xColumnName,HttpServletRequest request) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("xColumn", xColumnName);
params.put("yColumn", yColumnName);
EntityWrapper<KehuxinxiEntity> ew = new EntityWrapper<KehuxinxiEntity>();
String tableName = request.getSession().getAttribute("tableName").toString();
if(tableName.equals("yuangong")) {
ew.eq("yuangonggonghao", (String)request.getSession().getAttribute("username"));
}
List<Map<String, Object>> result = kehuxinxiService.selectValue(params, ew);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
for(Map<String, Object> m : result) {
for(String k : m.keySet()) {
if(m.get(k) instanceof Date) {
m.put(k, sdf.format((Date)m.get(k)));
}
}
}
return R.ok().put("data", result);
}
/**
* (按值统计)时间统计类型
*/
@RequestMapping("/value/{xColumnName}/{yColumnName}/{timeStatType}")
public R valueDay(@PathVariable("yColumnName") String yColumnName, @PathVariable("xColumnName") String xColumnName, @PathVariable("timeStatType") String timeStatType,HttpServletRequest request) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("xColumn", xColumnName);
params.put("yColumn", yColumnName);
params.put("timeStatType", timeStatType);
EntityWrapper<KehuxinxiEntity> ew = new EntityWrapper<KehuxinxiEntity>();
String tableName = request.getSession().getAttribute("tableName").toString();
if(tableName.equals("yuangong")) {
ew.eq("yuangonggonghao", (String)request.getSession().getAttribute("username"));
}
List<Map<String, Object>> result = kehuxinxiService.selectTimeStatValue(params, ew);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
for(Map<String, Object> m : result) {
for(String k : m.keySet()) {
if(m.get(k) instanceof Date) {
m.put(k, sdf.format((Date)m.get(k)));
}
}
}
return R.ok().put("data", result);
}
/**
* 分组统计
*/
@RequestMapping("/group/{columnName}")
public R group(@PathVariable("columnName") String columnName,HttpServletRequest request) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("column", columnName);
EntityWrapper<KehuxinxiEntity> ew = new EntityWrapper<KehuxinxiEntity>();
String tableName = request.getSession().getAttribute("tableName").toString();
if(tableName.equals("yuangong")) {
ew.eq("yuangonggonghao", (String)request.getSession().getAttribute("username"));
}
List<Map<String, Object>> result = kehuxinxiService.selectGroup(params, ew);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
for(Map<String, Object> m : result) {
for(String k : m.keySet()) {
if(m.get(k) instanceof Date) {
m.put(k, sdf.format((Date)m.get(k)));
}
}
}
return R.ok().put("data", result);
}
}
KehuxinxiServiceImpl.java
package com.service.impl;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.List;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.utils.PageUtils;
import com.utils.Query;
import com.dao.KehuxinxiDao;
import com.entity.KehuxinxiEntity;
import com.service.KehuxinxiService;
import com.entity.vo.KehuxinxiVO;
import com.entity.view.KehuxinxiView;
@Service("kehuxinxiService")
public class KehuxinxiServiceImpl extends ServiceImpl<KehuxinxiDao, KehuxinxiEntity> implements KehuxinxiService {
@Override
public PageUtils queryPage(Map<String, Object> params) {
Page<KehuxinxiEntity> page = this.selectPage(
new Query<KehuxinxiEntity>(params).getPage(),
new EntityWrapper<KehuxinxiEntity>()
);
return new PageUtils(page);
}
@Override
public PageUtils queryPage(Map<String, Object> params, Wrapper<KehuxinxiEntity> wrapper) {
Page<KehuxinxiView> page =new Query<KehuxinxiView>(params).getPage();
page.setRecords(baseMapper.selectListView(page,wrapper));
PageUtils pageUtil = new PageUtils(page);
return pageUtil;
}
@Override
public List<KehuxinxiVO> selectListVO(Wrapper<KehuxinxiEntity> wrapper) {
return baseMapper.selectListVO(wrapper);
}
@Override
public KehuxinxiVO selectVO(Wrapper<KehuxinxiEntity> wrapper) {
return baseMapper.selectVO(wrapper);
}
@Override
public List<KehuxinxiView> selectListView(Wrapper<KehuxinxiEntity> wrapper) {
return baseMapper.selectListView(wrapper);
}
@Override
public KehuxinxiView selectView(Wrapper<KehuxinxiEntity> wrapper) {
return baseMapper.selectView(wrapper);
}
@Override
public List<Map<String, Object>> selectValue(Map<String, Object> params, Wrapper<KehuxinxiEntity> wrapper) {
return baseMapper.selectValue(params, wrapper);
}
@Override
public List<Map<String, Object>> selectTimeStatValue(Map<String, Object> params, Wrapper<KehuxinxiEntity> wrapper) {
return baseMapper.selectTimeStatValue(params, wrapper);
}
@Override
public List<Map<String, Object>> selectGroup(Map<String, Object> params, Wrapper<KehuxinxiEntity> wrapper) {
return baseMapper.selectGroup(params, wrapper);
}
}
index.js
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg component
// register globally
Vue.component('svg-icon', SvgIcon)
const req = require.context('./svg/svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)