@TOC
springboot504基于Springboot网上蛋糕售卖店管理系统的设计与实现--论文pf
第1章 绪论
1.1选题动因
当前的网络技术,软件技术等都具备成熟的理论基础,市场上也出现各种技术开发的软件,这些软件都被用于各个领域,包括生活和工作的领域。随着电脑和笔记本的广泛运用,以及各种计算机硬件的完善和升级,市面上的电脑和笔记本的性能都得到提升,可以支持的软件也逐渐增多,因此,在计算机上安装软件来发挥其高效地信息处理的作用,则很受人们的青睐。对于网上蛋糕售卖店管理系统信息来讲,通过手工形式处理,在面对庞大的信息数量时,就显得不适宜了,首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,为了解决上述问题,有必要建立网上蛋糕售卖店管理系统,来规范网上蛋糕售卖店管理系统信息管理流程,让管理工作可以系统化和程序化,同时,网上蛋糕售卖店管理系统的有效运用可以帮助管理人员准确快速地处理信息。
1.2目的和意义
网上蛋糕售卖店管理系统可以对网上蛋糕售卖店管理系统信息进行集中管理,可以真正避免传统管理的缺陷。网上蛋糕售卖店管理系统是一款运用软件开发技术设计实现的应用系统,在信息处理上可以达到快速的目的,不管是针对数据添加,数据维护和统计,以及数据查询等处理要求,网上蛋糕售卖店管理系统都可以轻松应对。所以,网上蛋糕售卖店管理系统的运用是让网上蛋糕售卖店管理系统信息管理升级的最好方式。它可以实现信息处理的便利化要求,还可以规范信息处理的流程,让事务处理成为管理人员手中的一件简单事,而不是之前手工处理时的困难事。尽管网上蛋糕售卖店管理系统具备较完善的功能,但是也需要管理人员利用闲暇时间提升自身素质以及个人能力,在操作网上蛋糕售卖店管理系统时可以最大化运用网上蛋糕售卖店管理系统提供的功能,让系统在满足高效率处理数据的同时,也能始终稳定运行,还可以确保数据的可靠性与数据处理的质量。
1.3论文结构安排
本文总共分为6个章节,每个章节都对本系统描述了不同的内容。接下来就对本文的研究内容进行阐述。
第1章:这个章节是论文的绪论部分。从选题的背景和意义的角度阐述即将开发的系统。
第2章:这个章节是技术介绍部分。从本系统需要运用的技术知识的角度阐述系统。
第3章:这个章节是系统分析部分。从分析系统可行性,分析系统功能和性能等角度阐述系统。
第4章:这个章节是系统设计部分。从系统功能结构的角度和数据库设计的角度阐述系统。
第5章:这个章节是系统实现部分。从系统功能模块运行效果的角度阐述系统。
第6章:这个章节是系统测试部分。从测试系统功能,系统测试方法的角度阐述系统。
第2章 开发环境与技术
2.1 MySQL数据库
本研究与开发的应用程序在数据操作中难以预料,有时候甚至产生变化。没有办法直接在word中写数据,这不但不安全的,并且难以达到应用程序的功能。想要实现所需要的数据存放功能,务必选择专业数据库存储软件。在很多情况下,应用程序达到的功能并不是特别繁杂,市场中每一个有关数据库app都能实现。依据自己的思路结构与用户习惯,MySQL能够支持大中小型系统,且不应用Oracle、SQL Server 适用于大、中、小数据,适用于全方位的数据库,而非任何问题。由于真正意义上在线系统是数据库网站服务器和网络服务器。
2.2 Vue前端技术
在动态网站盛行之时,Java是一种高级编程语言。Sun企业上线了Servlet做为导出动态网站的标准规范。因为当时程序猿不是很喜欢,但一开始挑选很少。java语言在之后的好多个月里出现,不顾及性能高效率,最少区别了写网页页面所需要的动态性编码块和静态代码块,大大提升了创作效率易读性。因而,许多Java软件工程师选择java语言当作个人职业生涯发展前景。为保持Java语言在高级编程语言中的重要性,避免java再次抢占市场,Sun与Apache慈善基金会协作,开发了一种有关Java动态网站的技术规范,即vue技术性。vue在页面写作时吸取java语言中的所有优势,却也靠着Java语言 EE庞大环境能通过Java组件完成很多作用。这种组件能够直接引用到vue页面,使vue更强大和完善。确保了Java科技的竖向可持续发展观,最终在动态网站开发行业占有一席之地。别的java开发工作人员能够快速转移到vue开展开发,不顾及一些特殊组件或功能性的开发,自打动态性页面的开发来说,彻底完成了java流程和vue流程的基本无成本费变换,vue技术性就是这样发展趋势起来。
2.3 B/S架构模式
B/S架构是互联网行业区别C/S架构,用以叙述浏览器与服务器之间的架构方式。一般来说,挑选B/S架构的主要原因是维修方便。当软件开发时,能够在本地进行检测。一般综合开发工具都有各自的开发与一键部署。当地浏览器能够及时出效果。测试工程师有专业的网络服务器,仅需布署就可以。假如正中间有什么问题,能够整顿。应用软件更新,只需后台维护编码,顾客依然应用以前的浏览器开展访问,因此客户端十分方便。现在市面上大部分每一个电脑操作系统服务平台只要是有窗口模式,除开命令行操作页面对话框,窗口模式可以放置浏览器,因此一切带窗口模式的计算机操作系统自已的浏览器或其它生产商的浏览器,或挪动浏览器,都能够访问网络服务器。访问网络服务器占用客户端网络资源非常少,不易出差错。即便客户端有问题,也仅需重新装系统,随后组装浏览器就可以。在程序流程性能和用户体验层面,挑选B/S架构开发设计应用软件特别适合如今的社会的主力发展趋向。
2.4 ElementUI介绍
ElementUI是饿了么外卖前端团队上线的根据VUE2.0的组件库,是如今与VUE协作开发的更加好的UI库[33]。根据对各种各样软件系统的解读与优化,形成了一套详细解决方案,并把这种解决方法装包成可器重的界面模板供开发人员启用,减少了开发人员撰写应用软件难度,提升了软件质量。
ElementUI包括四个设计原理:一致性(Consistency)、意见反馈(Feedback)、高效率(Efficiency)、可控性(Controllability)。在软件开发环节中,这种设计原理根植于全部开发全过程。在其中,“一致性”指的是在全部开发环境里,所有功能都能够规范使用或操作,并保持一定的融洽,即手机软件应具有较好的实用性;“意见反馈”指的是在系统和用户互动过程中遇到不正确时,立即提供相关提醒和解决方法,以保证程序流程的正常使用;“高效率”指的是在新项目开发中,ElementUI有很多组件供开发人员挑选,由此可见,大大降低了开发人员生产制造轮子的时长,开发了通俗易懂的界面,协助用户快速开启系统软件;“可控性”规定产品具有充足强的可扩展性、扩展性和抗压强度,以便更好地适用别的应用软件。
它官网上有每一个组件Element,寻找所需要的组件,拷贝其编码,拷贝到工程项目所在位置。用户能通过电脑浏览器看到这样的组件在多个界面里的表明和两者之间的关联,并且可以改动删除他们。它具有较好的兼容模式,也支持自定义菜单作用。用户也可以根据给的正式文件,设定各种各样特性、事情、方法,使构件按照要求的形式产生变化。
此系统已经被应用 vue-admin-template基本上模板能够快速搭建后台管理界面。通过这些架构,大家能够快速构建一个界面清楚、实际操作简单实用、功能完善、维修方便的渠道。在这个基础上,开发能够节省了大量的开发时长,github上会有详尽的表明,非常容易快速查找难题。
第3章 系统分析
3.1 可行性分析
3.1.1技术可行性
研发设计程序流程挑选面向对象设计、功能齐全、简单实用的Java编程设计核心理念。MySQL数据库存储数据。Idea工具作为编程软件,win10计算机操作系统作为应用系统,以及数据库可视化工具等技术职称。一般来说,该程序流程的开发能够从技术上开展是可行的。
3.1.2经济可行性
开发的程序并不是向着商业服务程序方向设计与开发的,反而是做为毕业设计论文新项目开发的,主要运用于检测孩子在学校所学的知识,也锻练用户们使用互联网、书籍和别的方法进行自学能力。因而,该程序软件的开发不容易涉及到边际效益,也不会为软件的挑选付钱。你可以在开发软件的官网上下载所需要的软件,并根据要求的安装方法将软件安装在你的电脑中。一般来说,开发这一程序并没有经济发展开支。
3.1.3运行可行性
由于程序软件就是针对大部分一般操作用户,考虑到他的知识与文化水准,尤其开发了一个可操作度高的程序软件,能够轻而易举地让用户应用,数据可视化操作页面。一般来说,从用户操作程序的角度看,这一程序其实并不难操作。只需用户开启程序,就能避免专职人员学习培训开展程序作用操作,可以得出程序软件能够开发和操作。
3.2 系统流程
流程图这样的工具可以直观反映出系统内部的操作逻辑,可以帮助用户更好的理解系统。
3.2.1 操作信息流程
具体操作流程见下图
图3.1 操作流程图
3.2.2 登录信息流程
登录模块流程见下图
图3.2 登录流程图
3.2.3 删除信息流程
删除流程见下图。
图3.3 删除信息流程图
3.3 性能需求
需求分析报告包含依据用户的实际需要制订作用,及其将要定制的系统的性能需求分析报告。因而,在一般剖析系统时,一方面要剖析系统的功效,另一方面要搞清楚系统的性能。终究,一个性能好一点的系统的设计开发可以确保系统质量以及稳定性。
下面,从易学易用性、系统时间特性、系统稳定性等多个方面系统性能展开分析表明。
(1)系统容积规定:明确系统进行数据处理方法容量更大化。换句话说,假如系统建立模型容量临界点超出这一临界点,系统可能设备异常。
(2)系统精度规定:明确传送数据所需要的精度值,包含数值计算方法的精度值、数据信息精度系数的设定等。
(3)时长特点规定:系统建立模型有时限要求,那也是系统的时间也特点。一般剖析数据处理方法的时间也,设定用户标准的响应速度,及其系统在超负荷运行中能够偏移的范围值,要提前剖析明确。
(4)适应能力规定:当系统应对系统环境变化时,其融入这些变化的能力也要根据参数信息来反映。比如,应对变动的必须,系统必须通过强调必须设计方案的一个过程或系统来适应变化来反映系统的适应能力。
(5)易学易用性:除开作用应该考虑用户要求外,人机交互设计还要考虑到用户的用户习惯,包含界面风格、页面色彩选择与色彩搭配。尝试让用户接受简单学习后单独实际操作系统。
第4章 系统设计
市面上设计比较好的系统都有一个共同特征,就是主题鲜明突出。通过对页面简洁清晰的布局,让页面的内容,包括文字语言,或者视频图片等元素可以清晰表达出系统的主题。让来访用户无需花费过多精力和时间找寻需要的内容。
4.1界面设计原则
一般来说,大部分用户使用系统,有些是想从系统中获取需要的信息,有些则是使用系统提供的服务。所以,为了改善用户体验,提高系统的使用率,在对系统界面设计时,需要按照下面的原则进行。
第一点,对用户进行分析,了解用户使用系统的目的,以及使用系统的方式,考虑大部分用户的阅读习惯,设计Z字形或F型结构可以方便用户获取信息。
第二点:设计有效的导航,这个包括每个页面上都有导航条的显示,有时也可以在页面的底部设计导航条,当用户进入具体页面时,要设计相应的位置提示,在页面中比较特殊的位置,需要设计返回链接,可以返回上个页面,也可以返回首页等。
第三点:对整个系统要运用统一的设计方案,包括色彩方案的一致性,页面模板的相似性等,对相同操作和专业术语的描述在整个系统中也应该保持一致。
第四点:设计的界面要保证传达的内容清晰准确。要避免在同一个页面设计非常多的内容,另外可以准确对系统内容进行分类,把页面中用户视觉集中的位置,用来显示重要信息。
作为初学者,并没有那么多的设计经验,但是可以运用上面提到的界面设计原则设计出比较好的系统,可以让用户产生良好的使用体验。
4.2功能结构设计
为了让系统的编码可以顺利进行,特意对本系统功能进行细分设计,设计的系统功能结构见下图。
图4.1 系统功能结构图
4.3数据库设计
一般来说,对用户进行调查,了解其需求,主要还是完成功能上的分析设计,殊不知,设计功能时,也要展示对数据库的设计。数据库服务于程序,它可以按照设定的规则对程序的数据进行保存,因此,也可以说数据库就是程序相关数据的集合。为了保证程序的高质量,数据库提供的数据存储服务也需要快速响应,同时数据信息也要安全合法可靠,所以设计一个数据库这样的任务也需要高度重视,并花时间和精力去努力完成。毕竟这影响到后期程序的开发和使用。试想而知,假设设计一个不好的数据库,遇到的问题将会有:第一,面对信息处理,会有着繁琐的业务逻辑,延长事务处理时间。第二:程序编码期间,将会产生更多的代码去完成数据处理的功能,产生大量的数据冗余,而且也不方便注释代码,还会占用更多的存储空间。综上所述,设计出合理的数据库是多么的重要。
(1)下图是论坛实体和其具备的属性。
论坛实体属性图
(2)下图是商品实体和其具备的属性。
商品实体属性图
(3)下图是用户实体和其具备的属性。
用户实体属性图
(4)下图是公告信息实体和其具备的属性。
公告信息实体属性图
(5)下图是购物车实体和其具备的属性。
购物车实体属性图
(6)下图是商品收藏实体和其具备的属性。
商品收藏实体属性图
(7)下图是店员实体和其具备的属性。
店员实体属性图
(8)下图是商品评价实体和其具备的属性。
商品评价实体属性图
(9)下图是商品订单实体和其具备的属性。
商品订单实体属性图
(10)下图是收货地址实体和其具备的属性。
收货地址实体属性图
4.3.2 数据库物理设计
作为程序后台的支持,本数据库也需要设计数据存储的结构。而数据存储结构的设计就包括了数据表结构的设计和创建。数据表结构包括了字段,数据类型,还有字段的取值范围等信息。而E-R模型中的实体就是一张表,实体的特征就可以作为该表中的字段,根据本程序信息存储要求,设计每个字段需要的类型,还有该字段的取值范围等。每当设计完成一张数据表,就需要及时保存在数据库里面,并对该设计的数据表准确命名,要求设置的数据表的名称尽量不要是中文,而且要方便记忆。因为在程序编码阶段,通过SQL语句可以把程序里面的数据写入在各个数据表里面,而这个环节需要使用到数据表的名称。如果数据表名称是中文的话,可能会乱码并影响程序运行。下面就以表格形式展示设计的结果。
表4.1收货地址表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | yonghu_id | Integer | 创建用户 | 是 |
3 | address_name | String | 收货人 | 是 |
4 | address_phone | String | 电话 | 是 |
5 | address_dizhi | String | 地址 | 是 |
6 | isdefault_types | Integer | 是否默认地址 | 是 |
7 | insert_time | Date | 添加时间 | 是 |
8 | update_time | Date | 修改时间 | 是 |
9 | create_time | Date | 创建时间 | 是 |
表4.2购物车表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | yonghu_id | Integer | 所属用户 | 是 |
3 | dangao_id | Integer | 商品 | 是 |
4 | buy_number | Integer | 购买数量 | 是 |
5 | create_time | Date | 添加时间 | 是 |
6 | update_time | Date | 更新时间 | 是 |
7 | insert_time | Date | 创建时间 | 是 |
表4.3商品表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | dangao_name | String | 商品名称 | 是 |
3 | dangao_uuid_number | String | 商品编号 | 是 |
4 | dangao_photo | String | 商品照片 | 是 |
5 | dangao_types | Integer | 商品类型 | 是 |
6 | dangao_kucun_number | Integer | 商品库存 | 是 |
7 | dangao_price | Integer | 购买获得积分 | 是 |
8 | dangao_old_money | BigDecimal | 商品原价 | 是 |
9 | dangao_new_money | BigDecimal | 现价 | 是 |
10 | dangao_clicknum | Integer | 商品热度 | 是 |
11 | dangao_content | String | 商品介绍 | 是 |
12 | shangxia_types | Integer | 是否上架 | 是 |
13 | dangao_delete | Integer | 逻辑删除 | 是 |
14 | insert_time | Date | 录入时间 | 是 |
15 | create_time | Date | 创建时间 | 是 |
表4.4商品收藏表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | dangao_id | Integer | 商品 | 是 |
3 | yonghu_id | Integer | 用户 | 是 |
4 | dangao_collection_types | Integer | 类型 | 是 |
5 | insert_time | Date | 收藏时间 | 是 |
6 | create_time | Date | 创建时间 | 是 |
表4.5商品评价表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | dangao_id | Integer | 商品 | 是 |
3 | yonghu_id | Integer | 用户 | 是 |
4 | dangao_commentback_text | String | 评价内容 | 是 |
5 | insert_time | Date | 评价时间 | 是 |
6 | reply_text | String | 回复内容 | 是 |
7 | update_time | Date | 回复时间 | 是 |
8 | create_time | Date | 创建时间 | 是 |
表4.6商品订单表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | dangao_order_uuid_number | String | 订单号 | 是 |
3 | address_id | Integer | 收货地址 | 是 |
4 | dangao_id | Integer | 商品 | 是 |
5 | yonghu_id | Integer | 用户 | 是 |
6 | buy_number | Integer | 购买数量 | 是 |
7 | dangao_order_true_price | BigDecimal | 实付价格 | 是 |
8 | dangao_order_types | Integer | 订单类型 | 是 |
9 | dangao_order_payment_types | Integer | 支付类型 | 是 |
10 | insert_time | Date | 订单创建时间 | 是 |
11 | create_time | Date | 创建时间 | 是 |
表4.7店员表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | dianyuan_name | String | 店员名称 | 是 |
3 | dianyuan_phone | String | 联系方式 | 是 |
4 | dianyuan_email | String | 邮箱 | 是 |
5 | dianyuan_types | Integer | 店员类型 | 是 |
6 | dianyuan_content | String | 店员介绍 | 是 |
7 | dianyuan_delete | Integer | 逻辑删除 | 是 |
8 | create_time | Date | 创建时间 | 是 |
表4.8字典表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | dic_code | String | 字段 | 是 |
3 | dic_name | String | 字段名 | 是 |
4 | code_index | Integer | 编码 | 是 |
5 | index_name | String | 编码名字 | 是 |
6 | super_id | Integer | 父字段id | 是 |
7 | beizhu | String | 备注 | 是 |
8 | create_time | Date | 创建时间 | 是 |
表4.9论坛表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | forum_name | String | 帖子标题 | 是 |
3 | yonghu_id | Integer | 用户 | 是 |
4 | dianyuan_id | Integer | 店员 | 是 |
5 | users_id | Integer | 管理员 | 是 |
6 | forum_content | String | 发布内容 | 是 |
7 | super_ids | Integer | 父id | 是 |
8 | forum_state_types | Integer | 帖子状态 | 是 |
9 | insert_time | Date | 发帖时间 | 是 |
10 | update_time | Date | 修改时间 | 是 |
11 | create_time | Date | 创建时间 | 是 |
表4.10公告信息表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | news_name | String | 公告标题 | 是 |
3 | news_types | Integer | 商品信息 | 是 |
4 | news_photo | String | 公告图片 | 是 |
5 | insert_time | Date | 添加时间 | 是 |
6 | news_content | String | 公告详情 | 是 |
7 | create_time | Date | 创建时间 | 是 |
表4.11用户表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | yonghu_name | String | 用户姓名 | 是 |
3 | yonghu_phone | String | 联系方式 | 是 |
4 | yonghu_id_number | String | 身份证号 | 是 |
5 | yonghu_photo | String | 用户头像 | 是 |
6 | yonghu_email | String | 电子邮箱 | 是 |
7 | new_money | BigDecimal | 余额 | 是 |
8 | yonghu_sum_jifen | BigDecimal | 总积分 | 是 |
9 | yonghu_new_jifen | BigDecimal | 现积分 | 是 |
10 | huiyuandengji_types | Integer | 会员等级 | 是 |
11 | create_time | Date | 创建时间 | 是 |
表4.12管理员表
序号 | 列名 | 数据类型 | 说明 | 允许空 |
---|---|---|---|---|
1 | Id | Int | id | 否 |
2 | username | String | 用户名 | 是 |
3 | password | String | 密码 | 是 |
4 | role | String | 角色 | 是 |
5 | addtime | Date | 新增时间 | 是 |
第5章 系统实现
这个环节需要使用前面的设计方案,包括对系统模块的设计,还有对程序后台的数据支持的数据库的设计等。不过这部分内容还是强调系统编码人员的开发能力,要把前面设计的内容通过编码的形式以一个完整的,可以运行的系统呈现出来。
功能模块的实现
5.1用户信息管理
如图5.1显示的就是用户信息管理页面,此页面提供给管理员的功能有:用户信息的查询管理,可以删除用户信息、修改用户信息、新增用户信息,
还进行了对用户名称的模糊查询的条件
图5.1 用户信息管理页面
5.2 店员信息管理
如图5.2显示的就是店员信息管理页面,此页面提供给管理员的功能有:查看已发布的店员信息数据,修改店员信息,店员信息作废,即可删除,还进行了对店员信息名称的模糊查询 店员信息信息的类型查询等等一些条件。
图5.2 店员信息管理页面
5.3商品信息管理
如图5.3显示的就是商品信息管理页面,此页面提供给管理员的功能有:根据商品信息进行条件查询,还可以对商品信息进行新增、修改、查询操作等等。
图5.3 商品信息管理页面
5.1公告信息管理
如图5.4显示的就是公告信息管理页面,此页面提供给管理员的功能有:根据公告信息进行新增、修改、查询操作等等。
图5.4 公告信息管理页面
DictionaryServiceImpl.java
package com.service.impl;
import com.utils.StringUtil;
import com.service.DictionaryService;
import com.utils.ClazzDiff;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.lang.reflect.Field;
import java.util.*;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import com.utils.PageUtils;
import com.utils.Query;
import org.springframework.web.context.ContextLoader;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import com.dao.DictionaryDao;
import com.entity.DictionaryEntity;
import com.service.DictionaryService;
import com.entity.view.DictionaryView;
/**
* 字典 服务实现类
*/
@Service("dictionaryService")
@Transactional
public class DictionaryServiceImpl extends ServiceImpl<DictionaryDao, DictionaryEntity> implements DictionaryService {
@Override
public PageUtils queryPage(Map<String,Object> params) {
Page<DictionaryView> page =new Query<DictionaryView>(params).getPage();
page.setRecords(baseMapper.selectListView(page,params));
return new PageUtils(page);
}
/**
* 赋值给字典表
* @param obj view对象
*/
public void dictionaryConvert(Object obj, HttpServletRequest request) {
try {
if (obj == null) return;
//当前view和entity中的所有types的字段
List<String> fieldNameList = new ArrayList<>();
Class tempClass = obj.getClass();
while (tempClass !=null) {
Field[] declaredFields = tempClass.getDeclaredFields();
for (Field f : declaredFields) {
f.setAccessible(true);
if (f.getType().getName().equals("java.lang.Integer") && f.getName().contains("Types")) {
fieldNameList.add(f.getName());
}
}
tempClass = tempClass.getSuperclass(); //得到父类,然后赋给自己
}
// 获取监听器中的字典表
// ServletContext servletContext = ContextLoader.getCurrentWebApplicationContext().getServletContext();
ServletContext servletContext = request.getServletContext();
Map<String, Map<Integer, String>> dictionaryMap= (Map<String, Map<Integer, String>>) servletContext.getAttribute("dictionaryMap");
//通过Types的值给Value字段赋值
for (String s : fieldNameList) {
Field types = null;
if(hasField(obj.getClass(),s)){
//判断view中有没有这个字段,有就通过反射取出字段
types= obj.getClass().getDeclaredField(s);//获取Types私有字段
}else{
//本表中没有这个字段,说明它是父表中的字段,也就是entity中的字段,从entity中取值
types=obj.getClass().getSuperclass().getDeclaredField(s);
}
Field value = obj.getClass().getDeclaredField(s.replace("Types", "Value"));//获取value私有字段
//设置权限
types.setAccessible(true);
value.setAccessible(true);
//赋值
if (StringUtil.isNotEmpty(String.valueOf(types.get(obj)))) { //types的值不为空
int i = Integer.parseInt(String.valueOf(types.get(obj)));//type
//把s1字符中的所有大写转小写,并在前面加 _
char[] chars = s.toCharArray();
StringBuffer sbf = new StringBuffer();
for(int b=0; b< chars.length; b++){
char ch = chars[b];
if(ch <= 90 && ch >= 65){
sbf.append("_");
ch += 32;
}
sbf.append(ch);
}
String s2 = dictionaryMap.get(sbf.toString()).get(i);
value.set(obj, s2);
} else {
new Exception("字典表赋值出现问题::::"+value.getName());
value.set(obj, "");
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 判断本实体有没有这个字段
* @param c
* @param fieldName
* @return
*/
public boolean hasField(Class c, String fieldName){
Field[] fields = c.getDeclaredFields();
for (Field f : fields) {
if (fieldName.equals(f.getName())) {
return true;
}
}
return false;
}
}
DangaoController.java
package com.controller;
import java.io.File;
import java.math.BigDecimal;
import java.net.URL;
import java.text.SimpleDateFormat;
import com.alibaba.fastjson.JSONObject;
import java.util.*;
import org.springframework.beans.BeanUtils;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.context.ContextLoader;
import javax.servlet.ServletContext;
import com.service.TokenService;
import com.utils.*;
import java.lang.reflect.InvocationTargetException;
import com.service.DictionaryService;
import org.apache.commons.lang3.StringUtils;
import com.annotation.IgnoreAuth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.entity.*;
import com.entity.view.*;
import com.service.*;
import com.utils.PageUtils;
import com.utils.R;
import com.alibaba.fastjson.*;
/**
* 商品
* 后端接口
* @author
* @email
*/
@RestController
@Controller
@RequestMapping("/dangao")
public class DangaoController {
private static final Logger logger = LoggerFactory.getLogger(DangaoController.class);
private static final String TABLE_NAME = "dangao";
@Autowired
private DangaoService dangaoService;
@Autowired
private TokenService tokenService;
@Autowired
private AddressService addressService;//收货地址
@Autowired
private CartService cartService;//购物车
@Autowired
private DangaoCollectionService dangaoCollectionService;//商品收藏
@Autowired
private DangaoCommentbackService dangaoCommentbackService;//商品评价
@Autowired
private DangaoOrderService dangaoOrderService;//商品订单
@Autowired
private DianyuanService dianyuanService;//店员
@Autowired
private DictionaryService dictionaryService;//字典
@Autowired
private ForumService forumService;//论坛
@Autowired
private NewsService newsService;//公告信息
@Autowired
private YonghuService yonghuService;//用户
@Autowired
private UsersService usersService;//管理员
/**
* 后端列表
*/
@RequestMapping("/page")
public R page(@RequestParam Map<String, Object> params, HttpServletRequest request){
logger.debug("page方法:,,Controller:{},,params:{}",this.getClass().getName(),JSONObject.toJSONString(params));
String role = String.valueOf(request.getSession().getAttribute("role"));
if(false)
return R.error(511,"永不会进入");
else if("用户".equals(role))
params.put("yonghuId",request.getSession().getAttribute("userId"));
else if("店员".equals(role))
params.put("dianyuanId",request.getSession().getAttribute("userId"));
params.put("dangaoDeleteStart",1);params.put("dangaoDeleteEnd",1);
CommonUtil.checkMap(params);
PageUtils page = dangaoService.queryPage(params);
//字典表数据转换
List<DangaoView> list =(List<DangaoView>)page.getList();
for(DangaoView c:list){
//修改对应字典表字段
dictionaryService.dictionaryConvert(c, request);
}
return R.ok().put("data", page);
}
/**
* 后端详情
*/
@RequestMapping("/info/{id}")
public R info(@PathVariable("id") Long id, HttpServletRequest request){
logger.debug("info方法:,,Controller:{},,id:{}",this.getClass().getName(),id);
DangaoEntity dangao = dangaoService.selectById(id);
if(dangao !=null){
//entity转view
DangaoView view = new DangaoView();
BeanUtils.copyProperties( dangao , view );//把实体数据重构到view中
//修改对应字典表字段
dictionaryService.dictionaryConvert(view, request);
return R.ok().put("data", view);
}else {
return R.error(511,"查不到数据");
}
}
/**
* 后端保存
*/
@RequestMapping("/save")
public R save(@RequestBody DangaoEntity dangao, HttpServletRequest request){
logger.debug("save方法:,,Controller:{},,dangao:{}",this.getClass().getName(),dangao.toString());
String role = String.valueOf(request.getSession().getAttribute("role"));
if(false)
return R.error(511,"永远不会进入");
Wrapper<DangaoEntity> queryWrapper = new EntityWrapper<DangaoEntity>()
.eq("dangao_name", dangao.getDangaoName())
.eq("dangao_types", dangao.getDangaoTypes())
.eq("dangao_kucun_number", dangao.getDangaoKucunNumber())
.eq("dangao_price", dangao.getDangaoPrice())
.eq("shangxia_types", dangao.getShangxiaTypes())
.eq("dangao_delete", 1)
;
logger.info("sql语句:"+queryWrapper.getSqlSegment());
DangaoEntity dangaoEntity = dangaoService.selectOne(queryWrapper);
if(dangaoEntity==null){
dangao.setDangaoClicknum(1);
dangao.setShangxiaTypes(1);
dangao.setDangaoDelete(1);
dangao.setInsertTime(new Date());
dangao.setCreateTime(new Date());
dangaoService.insert(dangao);
return R.ok();
}else {
return R.error(511,"表中有相同数据");
}
}
/**
* 后端修改
*/
@RequestMapping("/update")
public R update(@RequestBody DangaoEntity dangao, HttpServletRequest request) throws NoSuchFieldException, ClassNotFoundException, IllegalAccessException, InstantiationException {
logger.debug("update方法:,,Controller:{},,dangao:{}",this.getClass().getName(),dangao.toString());
DangaoEntity oldDangaoEntity = dangaoService.selectById(dangao.getId());//查询原先数据
String role = String.valueOf(request.getSession().getAttribute("role"));
// if(false)
// return R.error(511,"永远不会进入");
if("".equals(dangao.getDangaoPhoto()) || "null".equals(dangao.getDangaoPhoto())){
dangao.setDangaoPhoto(null);
}
dangaoService.updateById(dangao);//根据id更新
return R.ok();
}
/**
* 删除
*/
@RequestMapping("/delete")
public R delete(@RequestBody Integer[] ids, HttpServletRequest request){
logger.debug("delete:,,Controller:{},,ids:{}",this.getClass().getName(),ids.toString());
List<DangaoEntity> oldDangaoList =dangaoService.selectBatchIds(Arrays.asList(ids));//要删除的数据
ArrayList<DangaoEntity> list = new ArrayList<>();
for(Integer id:ids){
DangaoEntity dangaoEntity = new DangaoEntity();
dangaoEntity.setId(id);
dangaoEntity.setDangaoDelete(2);
list.add(dangaoEntity);
}
if(list != null && list.size() >0){
dangaoService.updateBatchById(list);
}
return R.ok();
}
/**
* 批量上传
*/
@RequestMapping("/batchInsert")
public R save( String fileName, HttpServletRequest request){
logger.debug("batchInsert方法:,,Controller:{},,fileName:{}",this.getClass().getName(),fileName);
Integer yonghuId = Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId")));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//.eq("time", new SimpleDateFormat("yyyy-MM-dd").format(new Date()))
try {
List<DangaoEntity> dangaoList = new ArrayList<>();//上传的东西
Map<String, List<String>> seachFields= new HashMap<>();//要查询的字段
Date date = new Date();
int lastIndexOf = fileName.lastIndexOf(".");
if(lastIndexOf == -1){
return R.error(511,"该文件没有后缀");
}else{
String suffix = fileName.substring(lastIndexOf);
if(!".xls".equals(suffix)){
return R.error(511,"只支持后缀为xls的excel文件");
}else{
URL resource = this.getClass().getClassLoader().getResource("static/upload/" + fileName);//获取文件路径
File file = new File(resource.getFile());
if(!file.exists()){
return R.error(511,"找不到上传文件,请联系管理员");
}else{
List<List<String>> dataList = PoiUtil.poiImport(file.getPath());//读取xls文件
dataList.remove(0);//删除第一行,因为第一行是提示
for(List<String> data:dataList){
//循环
DangaoEntity dangaoEntity = new DangaoEntity();
// dangaoEntity.setDangaoName(data.get(0)); //商品名称 要改的
// dangaoEntity.setDangaoUuidNumber(data.get(0)); //商品编号 要改的
// dangaoEntity.setDangaoPhoto("");//详情和图片
// dangaoEntity.setDangaoTypes(Integer.valueOf(data.get(0))); //商品类型 要改的
// dangaoEntity.setDangaoKucunNumber(Integer.valueOf(data.get(0))); //商品库存 要改的
// dangaoEntity.setDangaoPrice(Integer.valueOf(data.get(0))); //购买获得积分 要改的
// dangaoEntity.setDangaoOldMoney(data.get(0)); //商品原价 要改的
// dangaoEntity.setDangaoNewMoney(data.get(0)); //现价 要改的
// dangaoEntity.setDangaoClicknum(Integer.valueOf(data.get(0))); //商品热度 要改的
// dangaoEntity.setDangaoContent("");//详情和图片
// dangaoEntity.setShangxiaTypes(Integer.valueOf(data.get(0))); //是否上架 要改的
// dangaoEntity.setDangaoDelete(1);//逻辑删除字段
// dangaoEntity.setInsertTime(date);//时间
// dangaoEntity.setCreateTime(date);//时间
dangaoList.add(dangaoEntity);
//把要查询是否重复的字段放入map中
//商品编号
if(seachFields.containsKey("dangaoUuidNumber")){
List<String> dangaoUuidNumber = seachFields.get("dangaoUuidNumber");
dangaoUuidNumber.add(data.get(0));//要改的
}else{
List<String> dangaoUuidNumber = new ArrayList<>();
dangaoUuidNumber.add(data.get(0));//要改的
seachFields.put("dangaoUuidNumber",dangaoUuidNumber);
}
}
//查询是否重复
//商品编号
List<DangaoEntity> dangaoEntities_dangaoUuidNumber = dangaoService.selectList(new EntityWrapper<DangaoEntity>().in("dangao_uuid_number", seachFields.get("dangaoUuidNumber")).eq("dangao_delete", 1));
if(dangaoEntities_dangaoUuidNumber.size() >0 ){
ArrayList<String> repeatFields = new ArrayList<>();
for(DangaoEntity s:dangaoEntities_dangaoUuidNumber){
repeatFields.add(s.getDangaoUuidNumber());
}
return R.error(511,"数据库的该表中的 [商品编号] 字段已经存在 存在数据为:"+repeatFields.toString());
}
dangaoService.insertBatch(dangaoList);
return R.ok();
}
}
}
}catch (Exception e){
e.printStackTrace();
return R.error(511,"批量插入数据异常,请联系管理员");
}
}
/**
* 个性推荐
*/
@IgnoreAuth
@RequestMapping("/gexingtuijian")
public R gexingtuijian(@RequestParam Map<String, Object> params, HttpServletRequest request){
logger.debug("gexingtuijian方法:,,Controller:{},,params:{}",this.getClass().getName(),JSONObject.toJSONString(params));
CommonUtil.checkMap(params);
List<DangaoView> returnDangaoViewList = new ArrayList<>();
//查询订单
Map<String, Object> params1 = new HashMap<>(params);params1.put("sort","id");params1.put("yonghuId",request.getSession().getAttribute("userId"));
PageUtils pageUtils = dangaoOrderService.queryPage(params1);
List<DangaoOrderView> orderViewsList =(List<DangaoOrderView>)pageUtils.getList();
Map<Integer,Integer> typeMap=new HashMap<>();//购买的类型list
for(DangaoOrderView orderView:orderViewsList){
Integer dangaoTypes = orderView.getDangaoTypes();
if(typeMap.containsKey(dangaoTypes)){
typeMap.put(dangaoTypes,typeMap.get(dangaoTypes)+1);
}else{
typeMap.put(dangaoTypes,1);
}
}
List<Integer> typeList = new ArrayList<>();//排序后的有序的类型 按最多到最少
typeMap.entrySet().stream().sorted((o1, o2) -> o2.getValue() - o1.getValue()).forEach(e -> typeList.add(e.getKey()));//排序
Integer limit = Integer.valueOf(String.valueOf(params.get("limit")));
for(Integer type:typeList){
Map<String, Object> params2 = new HashMap<>(params);params2.put("dangaoTypes",type);
PageUtils pageUtils1 = dangaoService.queryPage(params2);
List<DangaoView> dangaoViewList =(List<DangaoView>)pageUtils1.getList();
returnDangaoViewList.addAll(dangaoViewList);
if(returnDangaoViewList.size()>= limit) break;//返回的推荐数量大于要的数量 跳出循环
}
//正常查询出来商品,用于补全推荐缺少的数据
PageUtils page = dangaoService.queryPage(params);
if(returnDangaoViewList.size()<limit){//返回数量还是小于要求数量
int toAddNum = limit - returnDangaoViewList.size();//要添加的数量
List<DangaoView> dangaoViewList =(List<DangaoView>)page.getList();
for(DangaoView dangaoView:dangaoViewList){
Boolean addFlag = true;
for(DangaoView returnDangaoView:returnDangaoViewList){
if(returnDangaoView.getId().intValue() ==dangaoView.getId().intValue()) addFlag=false;//返回的数据中已存在此商品
}
if(addFlag){
toAddNum=toAddNum-1;
returnDangaoViewList.add(dangaoView);
if(toAddNum==0) break;//够数量了
}
}
}else {
returnDangaoViewList = returnDangaoViewList.subList(0, limit);
}
for(DangaoView c:returnDangaoViewList)
dictionaryService.dictionaryConvert(c, request);
page.setList(returnDangaoViewList);
return R.ok().put("data", page);
}
/**
* 前端列表
*/
@IgnoreAuth
@RequestMapping("/list")
public R list(@RequestParam Map<String, Object> params, HttpServletRequest request){
logger.debug("list方法:,,Controller:{},,params:{}",this.getClass().getName(),JSONObject.toJSONString(params));
CommonUtil.checkMap(params);
PageUtils page = dangaoService.queryPage(params);
//字典表数据转换
List<DangaoView> list =(List<DangaoView>)page.getList();
for(DangaoView c:list)
dictionaryService.dictionaryConvert(c, request); //修改对应字典表字段
return R.ok().put("data", page);
}
/**
* 前端详情
*/
@RequestMapping("/detail/{id}")
public R detail(@PathVariable("id") Long id, HttpServletRequest request){
logger.debug("detail方法:,,Controller:{},,id:{}",this.getClass().getName(),id);
DangaoEntity dangao = dangaoService.selectById(id);
if(dangao !=null){
//点击数量加1
dangao.setDangaoClicknum(dangao.getDangaoClicknum()+1);
dangaoService.updateById(dangao);
//entity转view
DangaoView view = new DangaoView();
BeanUtils.copyProperties( dangao , view );//把实体数据重构到view中
//修改对应字典表字段
dictionaryService.dictionaryConvert(view, request);
return R.ok().put("data", view);
}else {
return R.error(511,"查不到数据");
}
}
/**
* 前端保存
*/
@RequestMapping("/add")
public R add(@RequestBody DangaoEntity dangao, HttpServletRequest request){
logger.debug("add方法:,,Controller:{},,dangao:{}",this.getClass().getName(),dangao.toString());
Wrapper<DangaoEntity> queryWrapper = new EntityWrapper<DangaoEntity>()
.eq("dangao_name", dangao.getDangaoName())
.eq("dangao_uuid_number", dangao.getDangaoUuidNumber())
.eq("dangao_types", dangao.getDangaoTypes())
.eq("dangao_kucun_number", dangao.getDangaoKucunNumber())
.eq("dangao_price", dangao.getDangaoPrice())
.eq("dangao_clicknum", dangao.getDangaoClicknum())
.eq("shangxia_types", dangao.getShangxiaTypes())
.eq("dangao_delete", dangao.getDangaoDelete())
// .notIn("dangao_types", new Integer[]{102})
;
logger.info("sql语句:"+queryWrapper.getSqlSegment());
DangaoEntity dangaoEntity = dangaoService.selectOne(queryWrapper);
if(dangaoEntity==null){
dangao.setDangaoClicknum(1);
dangao.setDangaoDelete(1);
dangao.setInsertTime(new Date());
dangao.setCreateTime(new Date());
dangaoService.insert(dangao);
return R.ok();
}else {
return R.error(511,"表中有相同数据");
}
}
}
MPUtil.java
package com.utils;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.mapper.Wrapper;
/**
* Mybatis-Plus工具类
*/
public class MPUtil {
public static final char UNDERLINE = '_';
//mybatis plus allEQ 表达式转换
public static Map allEQMapPre(Object bean,String pre) {
Map<String, Object> map =BeanUtil.beanToMap(bean);
return camelToUnderlineMap(map,pre);
}
//mybatis plus allEQ 表达式转换
public static Map allEQMap(Object bean) {
Map<String, Object> map =BeanUtil.beanToMap(bean);
return camelToUnderlineMap(map,"");
}
public static Wrapper allLikePre(Wrapper wrapper,Object bean,String pre) {
Map<String, Object> map =BeanUtil.beanToMap(bean);
Map result = camelToUnderlineMap(map,pre);
return genLike(wrapper,result);
}
public static Wrapper allLike(Wrapper wrapper,Object bean) {
Map result = BeanUtil.beanToMap(bean, true, true);
return genLike(wrapper,result);
}
public static Wrapper genLike( Wrapper wrapper,Map param) {
Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
int i=0;
while (it.hasNext()) {
if(i>0) wrapper.and();
Map.Entry<String, Object> entry = it.next();
String key = entry.getKey();
String value = (String) entry.getValue();
wrapper.like(key, value);
i++;
}
return wrapper;
}
public static Wrapper likeOrEq(Wrapper wrapper,Object bean) {
Map result = BeanUtil.beanToMap(bean, true, true);
return genLikeOrEq(wrapper,result);
}
public static Wrapper genLikeOrEq( Wrapper wrapper,Map param) {
Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
int i=0;
while (it.hasNext()) {
if(i>0) wrapper.and();
Map.Entry<String, Object> entry = it.next();
String key = entry.getKey();
if(entry.getValue().toString().contains("%")) {
wrapper.like(key, entry.getValue().toString().replace("%", ""));
} else {
wrapper.eq(key, entry.getValue());
}
i++;
}
return wrapper;
}
public static Wrapper allEq(Wrapper wrapper,Object bean) {
Map result = BeanUtil.beanToMap(bean, true, true);
return genEq(wrapper,result);
}
public static Wrapper genEq( Wrapper wrapper,Map param) {
Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
int i=0;
while (it.hasNext()) {
if(i>0) wrapper.and();
Map.Entry<String, Object> entry = it.next();
String key = entry.getKey();
wrapper.eq(key, entry.getValue());
i++;
}
return wrapper;
}
public static Wrapper between(Wrapper wrapper,Map<String, Object> params) {
for(String key : params.keySet()) {
String columnName = "";
if(key.endsWith("_start")) {
columnName = key.substring(0, key.indexOf("_start"));
if(StringUtils.isNotBlank(params.get(key).toString())) {
wrapper.ge(columnName, params.get(key));
}
}
if(key.endsWith("_end")) {
columnName = key.substring(0, key.indexOf("_end"));
if(StringUtils.isNotBlank(params.get(key).toString())) {
wrapper.le(columnName, params.get(key));
}
}
}
return wrapper;
}
public static Wrapper sort(Wrapper wrapper,Map<String, Object> params) {
String order = "";
if(params.get("order") != null && StringUtils.isNotBlank(params.get("order").toString())) {
order = params.get("order").toString();
}
if(params.get("sort") != null && StringUtils.isNotBlank(params.get("sort").toString())) {
if(order.equalsIgnoreCase("desc")) {
wrapper.orderDesc(Arrays.asList(params.get("sort")));
} else {
wrapper.orderAsc(Arrays.asList(params.get("sort")));
}
}
return wrapper;
}
/**
* 驼峰格式字符串转换为下划线格式字符串
*
* @param param
* @return
*/
public static String camelToUnderline(String param) {
if (param == null || "".equals(param.trim())) {
return "";
}
int len = param.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = param.charAt(i);
if (Character.isUpperCase(c)) {
sb.append(UNDERLINE);
sb.append(Character.toLowerCase(c));
} else {
sb.append(c);
}
}
return sb.toString();
}
public static void main(String[] ages) {
System.out.println(camelToUnderline("ABCddfANM"));
}
public static Map camelToUnderlineMap(Map param, String pre) {
Map<String, Object> newMap = new HashMap<String, Object>();
Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, Object> entry = it.next();
String key = entry.getKey();
String newKey = camelToUnderline(key);
if (pre.endsWith(".")) {
newMap.put(pre + newKey, entry.getValue());
} else if (StringUtils.isEmpty(pre)) {
newMap.put(newKey, entry.getValue());
} else {
newMap.put(pre + "." + newKey, entry.getValue());
}
}
return newMap;
}
}
api.js
const api = {
// 积分订单
orderpage: 'orders/page',
orderdelete: 'orders/delete',
orderinfo: 'orders/info/',
ordersave: 'orders/save',
orderupdate: 'orders/update',
// 配置
configpage: 'config/page',
configdelete: 'config/delete',
configinfo: 'config/info/',
configsave: 'config/save',
configupdate: 'config/update'
}
export default api
声明
本博客适用于广泛的学术和教育用途,包括但不限于个人学习、开发设计,产品设计。仅供学习参考,旨在为读者提供深入理解和学术研究的材料。