




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
项目3
企业应用架构设计【学习目标】本项目主要学习企业应用架构设计、开发与部署,了解企业应用架构的设计思路,掌握使用Redis缓存用户登录信息、使用RocketMQ分布式消息系统完成高并发秒杀功能、实现系统日志消息采集;了解系统容器化的部署方式,掌握使用Docker镜像制作与部署各个服务,解决系统快速部署的问题。【项目介绍】将项目三的餐厅点餐系统使用企业应用架构的设计思路进行改造升级,基于企业应用架构实践,结合常用的技术框架实现秒杀活动热插拔模块、数据缓存、系统日志消息及系统的容器化部署。【知识结构】任务1.搭建前后端分离架构任务描述前后端分离已成为互联网项目开发的业界标准使用方式,本任务就是搭建前后端分离系统并实现用户管理模块。知识准备1.前后端分离
前后端分离已成为互联网项目开发的业界标准使用方式,通过nginx+tomcat的方式(也可以中间加一个nodejs)有效的进行解耦,并且前后端分离会为以后的大型分布式架构、弹性计算架构、微服务架构、多端化服务(多种客户端,例如:浏览器,车载终端,安卓,IOS等等)打下坚实的基础。这个从程序员成长为系统架构师的必经之路。前后端分离的核心思想是前端HTML页面通过AJAX调用后端的RESTFULAPI接口并使用JSON数据进行交互。2.Web服务器
一般指像Nginx,Apache这类的服务器,一般只能解析静态资源。3.应用服务器
一般指像Tomcat,Jetty,Resin这类的服务器可以解析动态资源也可以解析静态资源,但解析静态资源的能力没有web服务器好。4.Node.js
Node.js是一个基于ChromeV8引擎的JavaScript运行环境。Node.js使用了一个事件驱动、非阻塞式I/O的模型,使其轻量又高效。Node.js的包管理器npm,是全球最大的开源库生态系统。5.NPMNPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种:允许用户从NPM服务器下载别人编写的第三方包到本地使用。允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。任务实施步骤1:创建项目后台(1)使用SpringStarterProject创建项目,单击选择“File->New->Project”,在弹出的“NewProject”窗口选择“SrpingBoot->SpringStarterProject”,单击“Next”按钮,结果如图4-1所示:图4-1创建项目-1(2)在“NewSpringStarterProject”窗口,设置Name为“ordersys_bravo”,Group为“com.chinasofti”,JavaVersion为“8”,Package为“com.chinasofti.ordersys”,单击“Next”按钮,结果如图4-2所示:图4-2创建项目-2(3)在“NewSpringStarterProjectDependencies”窗口,单击选择“DeveloperTools->SpringBootDevTools”、“SQL->MyBatisFramework”、“SQL->MySQLDriver”、“Security->SpringSecurity”和“Web->SpringWeb”,单击“Finish”按钮,结果如图4-3所示:图4-3创建项目-3步骤2:修改项目依赖(1)打开pom.xml文件在dependencies中增加commons-lang3和jsonwebtoken依赖:<!--commons-lang3工具类 --><dependency> <groupId>mons</groupId> <artifactId>commons-lang3</artifactId></dependency><!--Token生成与解析--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.0</version></dependency>(2)在dependencies和build之间增加依赖管理配置:<dependencies><!--此处省略--></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><!--此处省略--></build>(3)修改build构建配置:<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><mainClass>com.chinasofti.ordersys.OrdersysBravoApplication</mainClass></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build>步骤3:进行项目配置(1)双击打开“ordersys_bravo\src\main\resources\application.yml”配置文件,注意文件后缀为yml。增加端口、日志、热编译、数据源、mybatis和token令牌设置,完整配置如下:server:port:8080
#指定打印日志配置logging:level:#定义项目mapper包下的日志打印机别为debugcom.chinasofti.ordersys.mapper:DEBUG
spring:profiles:active:dev#热编译devtools:restart:#需要实时更新的目录additional-paths:resources/**,static/**,templates/**
#数据源datasource:driver-class-name:com.mysql.cj.jdbc.Driverurl:jdbc:mysql://localhost:3306/ordersys-v3?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=UTCusername:rootpassword:rootplatform:mysqlmybatis:#指定实体类存放的包路径type-aliases-package:com.chinasofti.ordersys.model#指定mapper.xml文件的位置为/mybatis-mappers/下的所有xml文件mapper-locations:classpath:/mybatis-mappers/*#转换到驼峰命名configuration:mapUnderscoreToCamelCase:true
#token配置token:#令牌自定义标识header:Authorization#令牌秘钥#secret:abcdefghijklmnopqrstuvwxyzsecret:(OREDERSYS:)_$^11244^%$_(IS:)_@@++--(BAD:)_++++_.sds_(GUY:)#令牌有效期(默认30分钟)expireTime:60(2)在MySql8中创建数据库ordersys-v3,并设置数据库编码为UTF-8并导入提供的ordersys.sql文件。CREATESCHEMA`ordersys-v3`DEFAULTCHARACTERSETutf8;步骤4:引入通用代码引入JAVA项目通用代码,根据提供的项目资源代码复制到当前项目,结果如图4-4所示:图4-4导入项目通用代码导入通用代码的功能介绍见表4-1。表4-1任务1通用代码功能介绍表Constants.java通用常量信息。HttpStatus.java返回状态码。UserConstants.java用户常量信息。(2)“mon.core.lang”包下的唯一识别码基类。类名功能UUID.java提供通用唯一识别码。(3)“mon.core.text”包下的字符及格式转换基类。类名功能CharsetKit.java字符集工具类。Convert.java类型转换器。StrFormatter.java字符串格式化。类名功能(1)“mon.constant”包下的常量信息及状态码基类。(4)“mon.enums”包下的用户状态基类。类名功能UserStatus.java用户状态。(5)“mon.result”包下的响应信息基类。类名功能PageResults.java分页结果集对象。ResponseCode.java响应状态码消息枚举。Results.java响应结果封装对象。(6)“mon.security.filter”包下的权限过滤器基类。类名功能JwtAuthenticationTokenFilter.javatoken过滤器,用于验证token有效性。(7)“mon.security.handle”包下的授权认证失败基类。类名功能AuthenticationEntryPointImpl.java认证失败处理类,用于返回未授权。(8)“mon.security.service”包下的权限服务基类。类名功能SysLoginService.java登录校验服务类。TokenService.javatoken验证处理服务类。UserDetailsServiceImpl.java用户验证处理服务类。(9)“mon.security”包下的权限model基类。类名功能LoginUser.java登录用户身份权限的Model。(10)“com.chinasofti.ordersys.config”包下的项目全局配置类。类名功能ConfigurerAdapter.javaSpringWebMVC配置类。GlobalExceptionHandler.java全局异常控制类,用于拦截所有运行时的全局异常。SecurityConfig.javaSpringSecurity配置类。(11)“com.chinasofti.ordersys.util.http”包下的http工具类。类名功能ServletUtils.javaServlet客户端工具类。(12)“com.chinasofti.ordersys.util.security”包下的权限工具类。类名功能IdUtils.javaID生成器工具类。SecurityUtils.java安全服务工具类。UserHandleUtils用户控制工具类。(13)“com.chinasofti.ordersys.util”包下的字符串处理工具类。类名功能MyStringUtils.java字符串工具类。(14)“com.chinasofti.ordersys.model”包下的用户信息模型类。类名功能UserInfo.java用户信息模型类。(15)“com.chinasofti.ordersys.api.login”包下的用户登录接口类。类名功能LoginController.java用户登录接口类。(16)“com.chinasofti.ordersys.service.login”包下的用户登录服务类。类名功能LoginService.java用户登录服务类。(17)“com.chinasofti.ordersys.mapper”包下的用户登录映射类。类名功能LoginMapper.java用户登录映射类。步骤5:项目前端介绍(1)本项目提供基于vuejs和webpack构建的前端工程化项目“order-sys-front”,开发准备:1)安装node.js和vscode开发环境及工具2)熟悉npm命令3)熟悉vuejs框架及工具链(2)安装项目依赖
使用vscode工具打开项目“order-sys-front”。工具栏“终端->新终端”,在项目路径下输入“npminstall”命令安装项目依赖,结果如图4-5所示:图4-5安全前端项目依赖(3)启动项目安装项目依赖成功后,输入“npmrundev”在localhost:8181下运行项目,并启动热加载开发模式,结果如图4-6所示:图4-6启动项目成功(4)访问项目启动项目后访问打开浏览器并访问localhost:8181,结果如图4-7所示:图4-7项目首页(5)停止项目在终端界面按下“CTRL+C”,出现提示后输入“y”并按下“回车键”停止项目,结果如图4-8所示:图4-8停止前端项目知识小结【对应证书技能】1.掌握前后端分离架构设计的思想:前端负责View和Controller层,后端只负责Model层和Service层。2.把NodeJS当成跟前端交互的API。增加NodeJS中间层主要有以下优点:(1)适配性提升。(2)响应速度提升。(3)性能得到提升。(4)异步与模板统一。本任务知识技能点与等级证书技能的对应关系见表4-2。表4-2任务1知识技能点与等级证书技能对应任务1知识技能点对应证书技能知识点技能点工作领域工作任务职业技能要求等级前后端分离架构的开发1.掌握SpringBoot框架核心技术2.软件后端设计2.3服务接口设计2.3.1了解软件服务接口设计原则;2.3.2掌握RestfulAPI接口的作用与规范;2.3.3掌握服务接口的异常处理设计;2.3.4能够完成JWT的生成和校验,并完成鉴权设计和安全设计。高级2.掌握SpringSecurity框架核心技术3.掌握vuejs和webpack搭建前端框架谢谢观看任务2.实现用户管理模块任务描述本任务是基于前后端分离架构完成用户管理模块及相关功能。知识准备1.跨域介绍
跨域是指从一个域名的网页去请求另一个域名的资源。比如从页面去请求的资源。跨域的严格一点的定义是:只要协议、域名、端口有任何一个的不同,就被当作是跨域。2.前后端分离与跨域
前后端分离就是前端代码一个服务器,后端代码一个服务器,两个不同的服务之间需要互相请求对方的资源进行交互一般情况下是禁止的,就需要使用跨域来解决前后端分离的项目交互。3.跨域访问需要的技术:
由于浏览器一般不对script,img等进行跨域限制,所以我们有机会通过script的方式来实现跨域访问。
跨域访问需要用到两样技术,一个是JSON,一种基于文本的传输协议;另一种是JSONP跨域解决方案。任务实施步骤1:实现用户管理模块后台在“com.chinasofti.ordersys.api.admin”包中,新建AdminUserController类,用于实现用户管理模块接口。包含方法见表4-3。表4-3任务2AdminUserController类方法表方法名说明adminModify(UserInfoinfo)管理员修改用户信息的方法。deleteUser(IntegeruserId)删除用户。getUser(IntegeruserId)根据用户ID获取对应用户信息。getUserByPage(intpage)获取用户分页数据。modifyMyInfo(UserInfoinfo)修改个人信息。addUser(UserInfoinfo)新增用户。checkAddUser(StringuserAccount)检验用户是否存在。Ø代码如下:packagecom.chinasofti.ordersys.api.admin;
importmon.result.PageResults;importmon.result.Results;importcom.chinasofti.ordersys.model.UserInfo;importcom.chinasofti.ordersys.service.admin.UserService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.security.access.prepost.PreAuthorize;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;
importjava.util.List;importjava.util.stream.Collectors;
@PreAuthorize("hasRole('1')")@RestController@RequestMapping("/admin/user")publicclassAdminUserController{ @AutowiredUserServiceservice;
publicUserServicegetService(){ returnservice; } publicvoidsetService(UserServiceservice){ this.service=service; } @RequestMapping("/adminmodifyuser") publicResults<UserInfo>adminModify(UserInfoinfo){ if(info.getUserPass().isEmpty()){ info.setUserPass("1"); }
//执行修改操作 service.adminModify(info); returnResults.success(info); }
@RequestMapping("/deleteuser") publicResults<UserInfo>deleteUser(IntegeruserId){ service.deleteUser(userId); returnResults.success(); } @GetMapping("/get") publicResults<UserInfo>getUser(IntegeruserId){ UserInfouser=service.getUserById(userId); user.setUserPass(""); returnResults.success(user); }
@RequestMapping("/getuserbypage") publicPageResults<UserInfo>getUserByPage(intpage){
//获取最大页码数 intmaxPage=service.getMaxPage(10);
//对当前的页码数进行纠错,如果小于1,则直接显示第一页的内容 page=page<1?1:page;
//对当前的页码数进行纠错,如果大于最大页码,则直接显示最后一页的内容 page=page>maxPage?maxPage:page;
//进行分页数据查询 List<UserInfo>list=service.getByPage(page,10);
//过滤掉密码信息 list=list.stream().map(item->{item.setUserPass("");returnitem;}).collect(Collectors.toList());
//尝试将结果结构化 returnPageResults.success(list,page,maxPage); }
@RequestMapping("/modifyuser") publicResults<UserInfo>modifyMyInfo(UserInfoinfo){ service.modify(info);
//修改信息后需要自动注销 returnResults.success(info); }
@RequestMapping("/adduser") publicResults<UserInfo>addUser(UserInfoinfo){
//添加用户 service.addUser(info);
//跳转到用户管理界面 returnResults.success(info); }
@RequestMapping("/checkuser")
//获取请求参数中的用户名信息 publicResults<UserInfo>checkAddUser(@RequestParam("name")StringuserAccount){
//查询对应用户名的用户信息 List<UserInfo>list=service.findUserByName(userAccount);
//如果数据库中无数据 if(list.isEmpty()){
//输出可以添加标识 returnResults.success();
//如果数据库中有数据 }else{
//输出不能添加标识 returnResults.failure(); } }}在“com.chinasofti.ordersys.service.admin”包中,新建UserService类,用于实现用户管理模块服务。包含方法见表4-4。表4-4任务2UserService类方法表方法名说明adminModify(UserInfoinfo)管理员修改用户信息的方法。deleteUser(IntegeruserId)删除用户。getUserById(IntegeruserId)根据用户ID获取对应用户信息。findUserByName(StringuserAccount)根据用户名获取对应用户信息。getByPage(intpage,intpageSize)获取用户分页数据。getMaxPage(intpageSize)获取用户信息的最大页数。modify(UserInfoinfo)修改个人信息。addUser(UserInfoinfo)新增用户。checkPass(UserInfoinfo)验证用户用户名密码是否正确的方法Ø代码如下:packagecom.chinasofti.ordersys.service.admin;
importcom.chinasofti.ordersys.mapper.UserInfoMapper;importcom.chinasofti.ordersys.model.UserInfo;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;importorg.springframework.stereotype.Service;
importjava.util.List;
@ServicepublicclassUserService{ @AutowiredUserInfoMappermapper;
publicUserInfoMappergetMapper(){ returnmapper; }
publicvoidsetMapper(UserInfoMappermapper){ this.mapper=mapper; } /** *分页获取用户数据的方法 * *@parampage *要获取数据的页号 *@parampageSize *每页显示的条目数 *@return当前页的用户数据列表 **/ publicList<UserInfo>getByPage(intpage,intpageSize){ //获取带有连接池的数据库模版操作工具对象 intfirst=(1)*pageSize; //返回结果 returnmapper.getUserByPage(first,pageSize); }
/** *获取用户信息的最大页数 * *@parampageSize *每页显示的条目数 *@return当前数据库中数据的最大页数 **/ publicintgetMaxPage(intpageSize){
//获取最大页数信息 Longrows=mapper.getMaxPage(); //返回最大页数 return(int)((rows.longValue()-1)/pageSize+1); } /** *添加用户的方法 * *@paraminfo *需要添加的用户信息 **/ publicvoidaddUser(UserInfoinfo){
//创建加密工具
info.setUserPass(newBCryptPasswordEncoder().encode(info.getUserPass())); //执行用户信息插入操作 mapper.addUser(info); }
/** *删除用户的方法 * *@paramuserId *待删除用户的Id **/ publicvoiddeleteUser(IntegeruserId){ //获取带有连接池的数据库模版操作工具对象 mapper.deleteUser(userId); } /** *修改用户自身信息的方法 * *@paraminfo *需要修改的用户信息,其中userId属性指明需要修改的用户ID,其他信息为目标值,本人修改信息只能修改密码和头像 **/ publicvoidmodify(UserInfoinfo){ //获取带有连接池的数据库模版操作工具对象 info.setUserPass(newBCryptPasswordEncoder().encode(info.getUserPass())); //修改本人信息 mapper.modify(info);
}
/** *管理员修改用户信息的方法 * *@paraminfo *需要修改的用户信息,其中userId属性指明需要修改的用户ID,其他信息为目标值 **/ publicvoidadminModify(UserInfoinfo){ info.setUserPass(newBCryptPasswordEncoder().encode(info.getUserPass())); //修改本人信息 mapper.adminModify(info);
} /** *根据ID获取用户详细信息的方法 * *@paramuserId *需要获取详细信息的用户ID *@return返回查询到的用户详细信息 **/ publicUserInfogetUserById(IntegeruserId){
returnmapper.getUserById(userId); }
publicList<UserInfo>findUserByName(StringuserAccount){ returnmapper.findUsersByName(userAccount); }
/** *验证用户用户名密码是否正确的方法 * *@paraminfo *用于判定用户名、密码的用户对象 *@return用户名、密码是否验证通过,true表示用户名密码正确、false表示用户名或密码错误 **/ publicbooleancheckPass(UserInfoinfo){
//根据给定的用户名查询用户信息 List<UserInfo>userList=mapper.checkPass(info); //判定查询结果集合 //如果没有查询到任何数据 if(userList.isEmpty()){ //返回验证失败 returnfalse; } //如果查询到一条记录则判定密码是否一致 //构建加密对象 BCryptPasswordEncoderencoder=newBCryptPasswordEncoder(); //判定用户给定的密码和数据库中的密码是否一致 //如果一致,则返回true //如果不一致 //返回用户名、密码不匹配 //其他情况下返回验证失败 returnencoder.matches(info.getUserPass(),userList.get(0).getUserPass()); }}在“com.chinasofti.ordersys.mapper”包中,新建UserInfoMapper类,用于实现用户管理模块映射类。包含方法见表4-5。表4-5任务2UserInfoMapper类方法表方法名说明getAllUser()管理员修改用户信息的方法。addUser(UserInfoinfo)新增用户。getUserByPage(intfirst,intmax)获取用户分页数据。getMaxPage()获取用户信息的最大页数。deleteUser(IntegeruserId)删除用户。modify(UserInfoinfo)修改个人信息。adminModify(UserInfoinfo)管理员修改用户信息的方法。getUserById(IntegeruserId)根据用户ID获取对应用户信息。findUserByName(StringuserAccount)根据用户名获取对应用户信息。checkPass(UserInfoinfo)验证用户用户名密码是否正确的方法Ø代码如下:packagecom.chinasofti.ordersys.mapper;
importcom.chinasofti.ordersys.model.UserInfo;importorg.apache.ibatis.annotations.*;
importjava.util.List;
@MapperpublicinterfaceUserInfoMapper{
@Select("selectuserId,userAccount,userPass,locked,roleId,roleName,faceimgfromuserinfo,roleinfowhereuserinfo.role=roleinfo.roleIdorderbyuserId") publicList<UserInfo>getAllUser();
@Insert("insertintouserinfo(userAccount,userPass,role,faceImg)values(#{info.userAccount},#{info.userPass},#{info.roleId},#{info.faceimg})") @Options(useGeneratedKeys=true,keyProperty="info.userId") publicIntegeraddUser(@Param("info")UserInfouser);
@Select("selectuserId,userAccount,userPass,locked,roleId,roleName,faceimgfromuserinfo,roleinfowhereuserinfo.role=roleinfo.roleIdorderbyuserIdlimit#{first},#{max}") publicList<UserInfo>getUserByPage(@Param("first")intfirst,@Param("max")intmax);
@Select("selectcount(*)fromuserinfo") publicLonggetMaxPage();
@Delete("deletefromuserinfowhereuserId=#{userId}") publicvoiddeleteUser(@Param("userId")IntegeruserId); @Update("updateuserinfosetuserPass=#{info.userPass},faceimg=#{info.faceimg}whereuserId=#{info.userId}") publicvoidmodify(@Param("info")UserInfoinfo);
@Update("updateuserinfosetuserPass=#{info.userPass},faceimg=#{info.faceimg},role=#{info.roleId}whereuserId=#{info.userId}") publicvoidadminModify(@Param("info")UserInfoinfo);
@Select("selectuserId,userAccount,userPass,locked,roleId,roleName,faceimgfromuserinfo,roleinfowhereuserinfo.role=roleinfo.roleIdanduserId=#{userId}") publicUserInfogetUserById(@Param("userId")IntegeruserId);
@Select("selectuserId,userAccount,userPass,locked,roleId,roleNamefromuserinfo,roleinfowhereuserinfo.role=roleinfo.roleIdanduserinfo.userId=#{info.userId}") publicList<UserInfo>checkPass(@Param("info")UserInfoinfo);
@Select("selectuserId,userAccount,userPass,locked,roleId,roleName,faceimgfromuserinfo,roleinfowhereuserinfo.role=roleinfo.roleIdanduserinfo.userAccount=#{userAccount}") publicList<UserInfo>findUsersByName(@Param("userAccount")StringuserAccount);
}步骤2:实现用户管理模块前端(1)在“src\api”包中,新建user-admin-api.js,用于实现用户管理模块API接口。(2)在“src\views\user\”包中,新建index.vue,用于实现用户管理模块主界面。(3)在“src\views\user\”包中,新建detail.vue,用于实现用户明细界面。(4)在“src\views\user\”包中,新建user-constants.js,用于实现用户管理模块枚举类型数据转换。(5)把上述views的视图组件配置到路由src\router\index.js。注意:上述代码请参考提供的项目order-sys-front,此处省略。步骤3:启动项目并访问用户管理模块(1)启动项目后台,结果如图4-9所示:图4-9启动项目后台(2)启动项目前端,结果如图4-10所示:图4-10启动项目前端(3)打开浏览器访问http://localhost:8181,登录餐厅管理员账号并访问用户管理模块。角色用户对应密码关系见表4-6。系统角色用户名密码餐厅管理员aa1餐厅后厨bb1餐厅服务员cc1表4-6角色用户对应密码表结果如图4-11所示:图4-11用户管理模块页面知识小结【对应证书技能】1.前后端分离导致跨域问题,使用vue-cli搭建的vue项目,可以使用在项目内设置代理(proxyTable)的方式来解决跨域问题。其他方式搭建的前端项目,通过使用nginx启动前端服务同时配置代理。
本任务知识技能点与等级证书技能的对应关系见任务1的表4-2。谢谢观看任务3.实现菜品管理模块任务描述本任务将实现菜品(菜品)管理模块,分别完成菜品列表、菜品详情、添加菜品、修改菜品、删除菜品等功能。知识准备1.前端开发流程需求->原型->开发->测试->上线2.前端目录结构(1)模块化JS模块化:AMD、CommonJS、UMD、ES6ModuleCSS模块化:less、sass、stylus、postCSS、cssmodule资源模块化(2)组件化项目组定制化ui组件公共功能组件,如404,无权限公共插件模块间共用组件(3)静态资源管理非模块化资源模块化资源--与模块一起进行统一管理(4)规范化编码规范接口规范
git使用规范CodeReviewUI元素规范(5)国际化:减少层级引用,提高复用性3.测试(1)SIT测试环境
测试环境,前后端分离,后台CORS,前台通过代理跨域。最好采用sourcemap方式,利于追踪bug。一般测试通过,bug单清零,会转UAT测试。(2)UAT测试环境
用户验收测试,一般通过后,就准备部署上线。4.部署webpack进行打包后,发布到服务器上,项目上线。当然,上线前,要进行性能优化,例如配置缓存,静态资源CDN部署。任务实施步骤1:实现菜品管理模块后台(1)在“com.chinasofti.ordersys.model”包中,新建DishesInfo类,用于实现菜品信息视图对象。Ø代码如下:/***Copyright2015ChinaSoftInternationalLtd.Allrightsreserved.*/packagecom.chinasofti.ordersys.model;
/***<p>*Title:DishesInfo*</p>*<p>*Description:菜品信息VO*</p>*<p>*Copyright:Copyright(c)2015*</p>*<p>*Company:ChinaSoftInternationalLtd.*</p>**@authoretc*@version1.0*/publicclassDishesInfo{ /** *菜品ID **/ privateintdishesId; /** *菜品名称 **/ privateStringdishesName; /** *菜品描述 **/ privateStringdishesDiscript; /** *菜品图片 **/ privateStringdishesImg; /** *菜品详细描述文本 **/ privateStringdishesTxt; /** *是否推荐菜品标识 **/ privateintrecommend; /** *菜品单价 **/ privatefloatdishesPrice; privatefloatdishesPrice;
publicintgetDishesId(){ returndishesId; }
publicvoidsetDishesId(intdishesId){ this.dishesId=dishesId; }
publicStringgetDishesName(){ returndishesName; }
publicvoidsetDishesName(StringdishesName){ this.dishesName=dishesName; }
publicStringgetDishesDiscript(){ returndishesDiscript; }
publicvoidsetDishesDiscript(StringdishesDiscript){ this.dishesDiscript=dishesDiscript; }
publicStringgetDishesImg(){ returndishesImg; } publicvoidsetDishesImg(StringdishesImg){ this.dishesImg=dishesImg; }
publicStringgetDishesTxt(){ returndishesTxt; }
publicvoidsetDishesTxt(StringdishesTxt){ this.dishesTxt=dishesTxt; }
publicintgetRecommend(){ returnrecommend; }
publicvoidsetRecommend(intrecommend){ this.recommend=recommend; }
publicfloatgetDishesPrice(){ returndishesPrice; }
publicvoidsetDishesPrice(floatdishesPrice){ this.dishesPrice=dishesPrice; }}(2)在“com.chinasofti.ordersys.api.admin”包中,新建AdminDishesController类,用于实现菜品管理模块接口。Ø
代码如下:packagecom.chinasofti.ordersys.api.admin;
importmon.result.PageResults;importmon.result.Results;importcom.chinasofti.ordersys.model.DishesInfo;importcom.chinasofti.ordersys.service.admin.DishesService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.security.access.prepost.PreAuthorize;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;
importjava.util.List;@PreAuthorize("hasRole('1')")@RestController@RequestMapping("/admin/dishes")publicclassAdminDishesController{ @AutowiredDishesServiceservice;
publicDishesServicegetService(){ returnservice; }
publicvoidsetService(DishesServiceservice){ this.service=service; }
@RequestMapping("/adddishes") publicResults<DishesInfo>addDishes(DishesInfoinfo){ //执行添加菜品操作 service.addDishes(info);
returnResults.success(info); } @RequestMapping("/deletedishes") publicResults<DishesInfo>deleteDishes(IntegerdishesId){ service.deleteDishesById(dishesId); returnResults.success(); }
@GetMapping("/get") publicResults<DishesInfo>getDishes(IntegerdishesId){ returnResults.success(service.getDishesById(dishesId)); }
@RequestMapping("/getdishesbypage") publicPageResults<DishesInfo>getDishesInfoByPage(intpage){
//获取最大页码数 intmaxPage=service.getMaxPage(8); //对当前的页码数进行纠错,如果小于1,则直接显示第一页的内容 page=page<1?1:page; //对当前的页码数进行纠错,如果大于最大页码,则直接显示最后一页的内容 page=page>maxPage?maxPage:page; //进行分页数据查询 List<DishesInfo>list=service.getDishesInfoByPage(page,8); //尝试将结果结构化 returnPageResults.success(list,page,maxPage); }
@RequestMapping("/modifydishes") publicResults<DishesInfo>modifyDishes(DishesInfoinfo){
//执行菜品信息修改工作 service.modifyDishes(info);
//跳转到菜品管理界面 returnResults.success(info);
}
@RequestMapping("/toprecommend") publicResults<List<DishesInfo>>getTop4RecommendDishes(){
//获取头4条推荐菜品信息列表 List<DishesInfo>list=service.getTop4RecommendDishes(); //尝试将结果结构化 returnResults.success(list); }}(3)在“com.chinasofti.ordersys.service.admin”包中,新建DishesService类,用于实现菜品管理服务对象。Ø代码如下:/***Copyright2015ChinaSoftInternationalLtd.Allrightsreserved.*/packagecom.chinasofti.ordersys.service.admin;
importcom.chinasofti.ordersys.mapper.DishesInfoMapper;importcom.chinasofti.ordersys.model.DishesInfo;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;
importjava.util.List;/***<p>*Title:DishesService*</p>*<p>*Description:菜品管理服务对象*</p>*<p>*Copyright:Copyright(c)2015*</p>*<p>*Company:ChinaSoftInternationalLtd.*</p>**@authoretc*@version1.0*/@ServicepublicclassDishesService{ @AutowiredDishesInfoMappermapper;
publicDishesInfoMappergetMapper(){ returnmapper; }
publicvoidsetMapper(DishesInfoMappermapper){ this.mapper=mapper; }
/** *分页获取菜品数据的方法 * *@parampage *要获取数据的页号 *@parampageSize *每页显示的条目数 *@return当前页的菜品数据列表 **/ publicList<DishesInfo>getDishesInfoByPage(intpage,intpageSize){ //获取带有连接池的数据库模版操作工具对象 intfirst=(1)*pageSize; //返回结果 returnmapper.getDishesInfoByPage(first,pageSize);
}
/** *获取菜品信息的最大页数 * *@parampageSize *每页显示的条目数 *@return当前数据库中数据的最大页数 **/ publicintgetMaxPage(intpageSize){
Longrows=mapper.getMaxPage(); //返回最大页数 return(int)((rows.longValue()-1)/pageSize+1); } /** *根据菜品ID值删除菜品信息的方法 * *@paramdishesId *要删除的菜品Id **/ publicvoiddeleteDishesById(IntegerdishesId){ //获取带有连接池的数据库模版操作工具对象 mapper.deleteDishesById(dishesId); }
/** *添加菜品的方法 * *@paraminfo *需要添加的菜品信息 **/ publicvoidaddDishes(DishesInfoinfo){ mapper.addDishes(info);
} /** *根据dishesId获取菜品详细信息的方法 * *@paramdishesId *要获取信息的特定菜品Id *@return返回该id的菜品详细信息 **/ publicDishesInfogetDishesById(IntegerdishesId){
returnmapper.getDishesById(dishesId); }
/** *修改菜品信息的方法 * *@paramInfo *要修改的菜品信息,其中dishesId为修改依据,其余信息为修改的目标值 **/
publicvoidmodifyDishes(DishesInfoinfo){ mapper.modifyDishes(info); } /** *获取头4条推荐菜品的信息 * *@return头4条推荐菜品列表 **/ publicList<DishesInfo>getTop4RecommendDishes(){
returnmapper.getTop4RecommendDishes();
}}(4)在“com.chinasofti.ordersys.mapper”包中,新建DishesInfoMapper类,用于实现菜品模块映射类。Ø代码如下:packagecom.chinasofti.ordersys.mapper;
importcom.chinasofti.ordersys.model.DishesInfo;importorg.apache.ibatis.annotations.*;
importjava.util.List;
@MapperpublicinterfaceDishesInfoMapper{
@Select("select*fromdishesinfoorderbyrecommenddesc,dishesIdlimit#{first},#{max}") publicList<DishesInfo>getDishesInfoByPage(@Param("first")intfirst,@Param("max")intmax);
@Select("selectcount(*)fromdishesinfo") publicLonggetMaxPage();
@Delete("deletefromdishesinfowheredishesId=#{dishesId}") publicvoiddeleteDishesById(@Param("dishesId")IntegerdishesId); @Insert("insertintodishesinfo(dishesName,dishesDiscript,dishesTxt,dishesImg,recommend,dishesPrice)values(#{info.dishesName},#{info.dishesDiscript},#{info.dishesTxt},#{info.dishesImg},#{info.recommend},#{info.dishesPrice})") publicvoidaddDishes(@Param("info")DishesInfoinfo);
@Select("select*fromdishesinfowheredishesId=#{dishesId}") publicDishesInfogetDishesById(@Param("dishesId")IntegerdishesId);
@Update("updatedishesinfosetdishesName=#{info.dishesName},dishesDiscript=#{info.dishesDiscript},dishesTxt=#{info.dishesTxt},dishesImg=#{info.dishesImg},recommend=#{info.recommend},dishesPrice=#{info.dishesPrice}wheredishesId=#{info.dishesId}") publicvoidmodifyDishes(@Param("info")DishesInfoinfo);
@Select("select*fromdishesinfowhererecommend=1orderbydishesId") publicList<DishesInfo>getTop4RecommendDishes();
}步骤2:实现菜品管理模块前端(1)在“src\api”包中,新建dishes-api.js,用于实现菜品管理模块API接口。(2)在“src\views\dishes\”包中,新建index.vue,用于实现菜品管理模块主界面。
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 核电站钢结构模块化吊装工程验收及保修协议
- 返乡标兵就业协议书
- 项目结束清算协议书
- 事故车转让理赔协议书
- ktv管理承包协议书
- pvc水管合同协议书
- 逆风集团攻略协议书
- 门店部分转让协议书
- 养殖羊合作合同协议书
- 修理厂车辆质保协议书
- 丝网印刷技术全套讲解
- 《社会应急力量分类分级测评实施办法》知识培训
- 厦门理工学院应届生毕业论文答辩模板
- 24秋国家开放大学《社会教育及管理》形考任务1-3参考答案
- 机床电气控制技术(齐占庆)第一章-答案
- 《义务教育数学课程标准(2022年版)》初中内容解读
- 2024年汽车电器维修工(技师)职业资格鉴定考试题库(含答案)
- 医疗器械购置审批制度
- 2024年江西省高考化学试卷(真题+答案)
- 2024版民政局离婚协议书格式范文
- 安检五步法的安检流程
评论
0/150
提交评论