外星人电脑商城项目(四)

  • 如果需要源码,点赞+关注+留言备注邮箱,晚上统一发送
  • 外星人商城项目介绍
    • 项目背景
    • 项目功能
    • 项目技术
    • 项目模块
    • 项目要求
  • 外星人商城项目开发流程
    • 第一节 基础构建
    • 第二节 用户注册
    • 第三节 用户登录
    • 第四节 用户管理
      • 第一部分 密码修改
        • 1.修改密码-持久层
        • 2.修改密码-业务层
        • 3.修改密码-控制层
        • 4.修改密码-前端页面
      • 第二部分 个人资料
        • 1. 个人资料-持久层
        • 2. 个人资料-业务层
        • 3. 个人资料-控制层
        • 4. 个人资料-前端页面
      • 第三部分 上传头像
        • 1. 上传头像-持久层
        • 2. 上传头像-业务层
        • 3. 上传头像-控制层
        • 4. 上传头像-前端页面
    • 第五节 热销商品
    • 第六节 购物车
    • 第七节 订单
    • 第八节 商品秒杀
  • 外星人商城项目总结

如果需要源码,点赞+关注+留言备注邮箱,晚上统一发送

外星人商城项目介绍

项目背景

外星人公司(狗头)委托我开发一个一个专门的外星人商城(模仿京东、天猫),出售外星人电子产品以及周边,实现了以下功能。
本项目已经搭载了服务器,网址给定:
链接: 外星人官方网站.

项目功能

  • 登录
  • 注册
  • 用户管理
  • 热销商品
  • 购物车
  • 订单
  • 商品秒杀

项目技术

  • 项目框架:springboot
  • 数据库框架:mybaits
  • 前端技术:JS、JQuery、Ajax

项目模块

持久层:依据业务要求规划相关的SQL语句,以及进行配置
业务层:核心功能控制、业务操作以及异常处理
控制层:接受请求,处理响应
前端开发:JS、JQuery、Ajax
单元测试:junit

项目要求

  • JDK8
  • maven3.6.1
  • 数据库mysql5.1
  • idea

外星人商城项目开发流程

第一节 基础构建

第二节 用户注册

第三节 用户登录

第四节 用户管理

今天来完成新的模块

第一部分 密码修改

1.修改密码-持久层

规划内容,编写sql语句
首先,查询用户是否存在

    /*** 根据用户名查询用户数据* @param username 用户名* @return 匹配的用户数据,如果没有匹配的数据,则返回null*/User findByUsername(String username);
    /*** 根据uid更新用户的密码* @param uid 用户的id* @param password 新密码* @param modifiedUser 最后修改执行人* @param modifiedTime 最后修改时间* @return 受影响的行数*/Integer updatePasswordByUid(@Param("uid") Integer uid,@Param("password") String password,@Param("modifiedUser") String modifiedUser,@Param("modifiedTime") Date modifiedTime);/*Integer updatePasswordByUid(Integer uid,String password,String modifiedUser,Date modifiedTime); */
    <!-- 根据用户名查询用户数据:User findByUsername(String username) --><select id="findByUsername" resultMap="UserEntityMap">SELECT*FROMcompution.t_userWHEREusername = #{username}</select>
    <!-- 根据uid更新用户的密码:Integer updatePasswordByUid(@Param("uid") Integer uid,@Param("password") String password,@Param("modifiedUser") String modifiedUser,@Param("modifiedTime") Date modifiedTime) --><update id="updatePasswordByUid">UPDATEcompution.t_userSETpassword = #{password},modified_user = #{modifiedUser},modified_time = #{modifiedTime}WHEREuid = #{uid}</update>

2.修改密码-业务层

    /*** 修改密码* @param uid 当前登录的用户id* @param username 用户名* @param oldPassword 原密码* @param newPassword 新密码*/public void changePassword(Integer uid, String username, String oldPassword, String newPassword);
    @Overridepublic void changePassword(Integer uid, String username, String oldPassword, String newPassword) {// 调用userMapper的findByUid()方法,根据参数uid查询用户数据User result = userMapper.findByUid(uid);// 检查查询结果是否为nullif (result == null) {// 是:抛出UserNotFoundException异常throw new UserNotFoundException("用户数据不存在");}// 检查查询结果中的isDelete是否为1if (result.getIsDelete().equals(1)) {// 是:抛出UserNotFoundException异常throw new UserNotFoundException("用户数据不存在");}// 从查询结果中取出盐值String salt = result.getSalt();// 将参数oldPassword结合盐值加密,得到oldMd5PasswordString oldMd5Password = getMd5Password(oldPassword, salt);// 判断查询结果中的password与oldMd5Password是否不一致if (!result.getPassword().contentEquals(oldMd5Password)) {// 是:抛出PasswordNotMatchException异常throw new PasswordNotMatchException("原密码错误");}// 将参数newPassword结合盐值加密,得到newMd5PasswordString newMd5Password = getMd5Password(newPassword, salt);// 创建当前时间对象Date now = new Date();// 调用userMapper的updatePasswordByUid()更新密码,并获取返回值Integer rows = userMapper.updatePasswordByUid(uid, newMd5Password, username, now);// 判断以上返回的受影响行数是否不为1if (rows != 1) {// 是:抛出UpdateException异常throw new UpdateException("更新用户数据时出现未知错误,请联系系统管理员");}}

3.修改密码-控制层

异常处理

        } else if (e instanceof InsertException) {result.setState(5000);} else if (e instanceof UpdateException) {result.setState(5001);
    @GetMapping("get_by_uid")public JsonResult<User> getByUid(HttpSession session) {// 从HttpSession对象中获取uidInteger uid = getUidFromSession(session);// 调用业务对象执行获取数据User data = userService.getByUid(uid);// 响应成功和数据return new JsonResult<User>(OK, data);}
//    public JsonResult<Void> changePassword(String oldPassword, String newPassword, HttpSession session) {public String changePassword(String oldPassword, String newPassword, HttpSession session) {// 调用session.getAttribute("")获取uid和usernameInteger uid = getUidFromSession(session);String username = getUsernameFromSession(session);// 调用业务对象执行修改密码userService.changePassword(uid, username, oldPassword, newPassword);// 返回成功
//        return new JsonResult<Void>(OK);return "redirect:/web/login.html";}

4.修改密码-前端页面

<form id="form-change-password" class="form-horizontal" role="form">
    @RequestMapping("change_password")
  • @RequestMapping除了可以指定URL映射外,还可以指定“请求方法、请求参数和请求头”的映射请求
  • @RequestMapping来映射URL
<!--修改密码表单开始-->
<form id="form-change-password" class="form-horizontal" role="form"><div class="form-group"><label class="col-md-2 control-label">原密码:</label><div class="col-md-8"><input name="oldPassword" type="text" class="form-control" placeholder="请输入原密码"></div></div><div class="form-group"><label class="col-md-2 control-label">新密码:</label><div class="col-md-8"><input name="newPassword" type="text" class="form-control" placeholder="请输入新密码"></div></div><div class="form-group"><label class="col-md-2 control-label">确认密码:</label><div class="col-md-8"><input type="text" class="form-control" placeholder="请再次输入新密码"></div></div><div class="form-group"><div class="col-sm-offset-2 col-sm-10"><input id="btn-change-password" type="button" class="btn btn-primary" value="修改" /></div></div>
</form>

ajax

     <!--页脚结束--><script type="text/javascript">$("#btn-change-password").click(function() {$.ajax({url: "/users/change_password",type: "POST",data: $("#form-change-password").serialize(),dataType: "json",success: function(json) {if (json.state == 200) {alert("修改成功!");} else {alert("修改失败!" + json.message);}},error: function (xhr) {alert("您的登录信息已经过期,请重新登录!HTTP响应码:" + xhr.status);location.href = "login.html";}});});</script>

第二部分 个人资料

1. 个人资料-持久层

这里发现我对于mybatis中的判断这种不懂,需要回顾

    <!-- 根据uid更新用户个人资料:Integer updateInfoByUid(User user) --><update id="updateInfoByUid">UPDATEcompution.t_userSET<if test="phone != null">phone = #{phone},</if><if test="email != null">email = #{email},</if><if test="gender != null">gender = #{gender},</if>modified_user = #{modifiedUser},modified_time = #{modifiedTime}WHEREuid = #{uid}</update>

2. 个人资料-业务层

    /*** 根据uid更新用户资料* @param user 封装了用户id和新个人资料的对象* @return 受影响的行数*/Integer updateInfoByUid(User user);
@Overridepublic void changeInfo(Integer uid, String username, User user) {// 调用userMapper的findByUid()方法,根据参数uid查询用户数据User result = userMapper.findByUid(uid);// 判断查询结果是否为nullif (result == null) {// 是:抛出UserNotFoundException异常throw new UserNotFoundException("用户数据不存在");}// 判断查询结果中的isDelete是否为1if (result.getIsDelete().equals(1)) {// 是:抛出UserNotFoundException异常throw new UserNotFoundException("用户数据不存在");}// 向参数user中补全数据:uiduser.setUid(uid);// 向参数user中补全数据:modifiedUser(username)user.setModifiedUser(username);// 向参数user中补全数据:modifiedTime(new Date())user.setModifiedTime(new Date());// 调用userMapper的updateInfoByUid(User user)方法执行修改,并获取返回值Integer rows = userMapper.updateInfoByUid(user);// 判断以上返回的受影响行数是否不为1if (rows != 1) {// 是:抛出UpdateException异常throw new UpdateException("更新用户数据时出现未知错误,请联系系统管理员");}}

3. 个人资料-控制层

这里要进行异常处理

        } else if (e instanceof UpdateException) {result.setState(5001);
    @RequestMapping("change_info")public JsonResult<Void> changeInfo(User user, HttpSession session) {// 从HttpSession对象中获取uid和usernameInteger uid = getUidFromSession(session);String username = getUsernameFromSession(session);// 调用业务对象执行修改用户资料userService.changeInfo(uid, username, user);// 响应成功return new JsonResult<Void>(OK);}

4. 个人资料-前端页面

                     <!--修改资料表单开始--><form id="form-change-info" class="form-horizontal" role="form"><div class="form-group"><label class="col-md-2 control-label">用户名:</label><div class="col-md-8"><input id="username" type="text" class="form-control" value="孙悟空" readonly="readonly"></div></div><div class="form-group"><label class="col-md-2 control-label">电话号码:</label><div class="col-md-8"><input id="phone" name="phone" type="text" class="form-control" placeholder="请输入电话号码" value="13311311313"></div></div><div class="form-group"><label class="col-md-2 control-label">电子邮箱:</label><div class="col-md-8"><input id="email" name="email" type="text" class="form-control" placeholder="请输入电子邮箱" value="sunwk@qq.com"></div></div><div class="form-group"><label class="col-md-2 control-label">性别:</label><div class="col-md-8"><label class="radio-inline"><input id="gender-male" type="radio" name="gender" value="1" >男</label><label class="radio-inline"><input id="gender-female" type="radio" name="gender" value="0">女</label></div></div><div class="form-group"><div class="col-sm-offset-2 col-sm-10"><input id="btn-change-info" type="button" class="btn btn-primary" value="修改" /></div></div></form>
     <script type="text/javascript">$(document).ready(function() {$.ajax({url: "/users/get_by_uid",type: "GET",dataType: "json",success: function(json) {if (json.state == 200) {console.log("username=" + json.data.username);console.log("phone=" + json.data.phone);console.log("email=" + json.data.email);console.log("gender=" + json.data.gender);$("#username").val(json.data.username);$("#phone").val(json.data.phone);$("#email").val(json.data.email);let radio = json.data.gender == 0 ? $("#gender-female") : $("#gender-male");radio.prop("checked", "checked");} else {alert("获取用户信息失败!" + json.message);}}});});$("#btn-change-info").click(function() {$.ajax({url: "/users/change_info",type: "POST",data: $("#form-change-info").serialize(),dataType: "json",success: function(json) {if (json.state == 200) {alert("修改成功!");location.href = "login.html";} else {alert("修改失败!" + json.message);}},error: function(xhr) {alert("您的登录信息已经过期,请重新登录!HTTP响应码:" + xhr.status);location.href = "login.html";}});});</script>

第三部分 上传头像

1. 上传头像-持久层

老样子,接口和sql语句

    /*** 根据uid更新用户的头像* @param uid 用户的id* @param avatar 新头像的路径* @param modifiedUser 修改执行人* @param modifiedTime 修改时间* @return 受影响的行数*/Integer updateAvatarByUid(@Param("uid") Integer uid,@Param("avatar") String avatar,@Param("modifiedUser") String modifiedUser,@Param("modifiedTime") Date modifiedTime);
    <!-- 根据uid更新用户的头像Integer updateAvatarByUid(@Param("uid") Integer uid,@Param("avatar") String avatar,@Param("modifiedUser") String modifiedUser,@Param("modifiedTime") Date modifiedTime) --><update id="updateAvatarByUid">UPDATEcompution.t_userSETavatar = #{avatar},modified_user = #{modifiedUser},modified_time = #{modifiedTime}WHEREuid = #{uid}</update>

2. 上传头像-业务层

avatar:/upload/9c8dacd6-9f73-4c60-87ad-270eba65f24c.png
    /*** 修改用户头像* @param uid 当前登录的用户的id* @param username 当前登录的用户名* @param avatar 用户的新头像的路径*/void changeAvatar(Integer uid, String username, String avatar);
    @Overridepublic void changeAvatar(Integer uid, String username, String avatar) {// 调用userMapper的findByUid()方法,根据参数uid查询用户数据User result = userMapper.findByUid(uid);// 检查查询结果是否为nullif (result == null) {// 是:抛出UserNotFoundExceptionthrow new UserNotFoundException("用户数据不存在");}// 检查查询结果中的isDelete是否为1if (result.getIsDelete().equals(1)) {// 是:抛出UserNotFoundExceptionthrow new UserNotFoundException("用户数据不存在");}// 创建当前时间对象Date now = new Date();// 调用userMapper的updateAvatarByUid()方法执行更新,并获取返回值Integer rows = userMapper.updateAvatarByUid(uid, avatar, username, now);// 判断以上返回的受影响行数是否不为1if (rows != 1) {// 是:抛出UpdateExceptionthrow new UpdateException("更新用户数据时出现未知错误,请联系系统管理员");}}

3. 上传头像-控制层

    @PostMapping("change_avatar")public JsonResult<String> changeAvatar(@RequestParam("file") MultipartFile file, HttpSession session) {// 判断上传的文件是否为空if (file.isEmpty()) {// 是:抛出异常throw new FileEmptyException("上传的头像文件不允许为空");}// 判断上传的文件大小是否超出限制值if (file.getSize() > AVATAR_MAX_SIZE) { // getSize():返回文件的大小,以字节为单位// 是:抛出异常throw new FileSizeException("不允许上传超过" + (AVATAR_MAX_SIZE / 1024) + "KB的头像文件");}// 判断上传的文件类型是否超出限制String contentType = file.getContentType();// boolean contains(Object o):当前列表若包含某元素,返回结果为true;若不包含该元素,返回结果为falseif (!AVATAR_TYPES.contains(contentType)) {// 是:抛出异常throw new FileTypeException("不支持使用该类型的文件作为头像,允许的文件类型:" + AVATAR_TYPES);}// 获取当前项目的绝对磁盘路径String parent = session.getServletContext().getRealPath("upload");System.out.println(parent);// 保存头像文件的文件夹File dir = new File(parent);if (!dir.exists()) {dir.mkdirs();}// 保存的头像文件的文件名String suffix = "";String originalFilename = file.getOriginalFilename();int beginIndex = originalFilename.lastIndexOf(".");if (beginIndex > 0) {suffix = originalFilename.substring(beginIndex);}String filename = UUID.randomUUID().toString() + suffix;// 创建文件对象,表示保存的头像文件File dest = new File(dir, filename);// 执行保存头像文件try {file.transferTo(dest);} catch (IllegalStateException e) {// 抛出异常throw new FileStateException("文件状态异常,可能文件已被移动或删除");} catch (IOException e) {// 抛出异常throw new FileUploadIOException("上传文件时读写错误,请稍后重新尝试");}// 头像路径String avatar = "/upload/" + filename;// 从Session中获取uid和usernameInteger uid = getUidFromSession(session);String username = getUsernameFromSession(session);// 将头像写入到数据库中userService.changeAvatar(uid, username, avatar);// 返回成功头像路径return new JsonResult<String>(OK, avatar);}

4. 上传头像-前端页面

<!--上传头像表单开始-->
<form id="form-change-avatar" class="form-horizontal" role="form"><div class="form-group"><label class="col-md-2 control-label">选择头像:</label><div class="col-md-5"><img id="img-avatar" src="../images/index/user.jpg" class="img-responsive" /></div><div class="clearfix"></div><div class="col-md-offset-2 col-md-4"><input type="file" name="file"></div></div><div class="form-group"><div class="col-sm-offset-2 col-sm-10"><input id="btn-change-avatar" type="button" class="btn btn-primary" value="上传" /></div></div>
</form>
<script type="text/javascript">$(document).ready(function () {console.log("cookie中的avatar=" + $.cookie("avatar"));$("#img-avatar").attr("src", $.cookie("avatar"));});$("#btn-change-avatar").click(function() {$.ajax({url: "/users/change_avatar",type: "POST",data: new FormData($("#form-change-avatar")[0]),dataType: "JSON",processData: false, // processData处理数据contentType: false, // contentType发送数据的格式success: function(json) {if (json.state == 200) {$("#img-avatar").attr("src", json.data);$.cookie("avatar", json.data, {expires: 7});} else {alert("修改失败!" + json.message);}},error: function(xhr) {alert("您的登录信息已经过期,请重新登录!HTTP响应码:" + xhr.status);location.href = "login.html";}});});</script>

第五节 热销商品

第六节 购物车

第一部分 加入购物车
第二部分 显示购物车
第三部分 购物车商品数量
第四部分 勾选数据

第七节 订单

第八节 商品秒杀

外星人商城项目总结

基于springboot的外星人电脑商城项目(四)(用户管理)相关推荐

  1. 基于SpringBoot vue的电脑商城平台源码和论文含支付宝沙箱支付

    演示视频: 基于SpringBoot vue的电脑商城平台源码和论文含支付宝沙箱支付演示视频 支付宝沙箱: package com.java.controller;import java.util.* ...

  2. 使用SpringBoot编写电脑商城项目笔记(每一步都详细记录,前后端数据交互使用html+ajax+json)

    项目环境 JDK1.8 Maven3.8.3 Tomcat9.0.54 Mysql8.0 技术栈:springboot+mybatis+mysql+html+javascript+css+json+j ...

  3. 基于springboot的外星人官方笔记本商城(序言)

    基于springboot的外星人官方笔记本商城(序言 如果需要源码,点赞+关注+留言备注邮箱,晚上统一发送 基于springboot的外星人官方笔记本商城(序言) 项目背景 项目功能 项目技术 项目模 ...

  4. SpringBoot项目电脑商城项目实战(适合刚学完SpringBoot的初学者)

    今天来分享一个SpringBoot项目,该项目是哔哩哔哩袁庭新老师讲的springboot电脑商城项目,里面的东西涉及到很多基础,统一异常处理,统一结果集返回,登录注册,上传文件等. 另外项目里使用的 ...

  5. 轻松搭建基于 SpringBoot Vue 的 Web 商城应用

    背景介绍 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数 ...

  6. Serverless 实战 —— 轻松搭建基于 SpringBoot + Vue 的 Web 商城应用

    Serverless 实战 -- 轻松搭建基于 SpringBoot + Vue 的 Web 商城应用 背景介绍 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute ...

  7. 图片管理系统源码_「程序员分享」基于SpringBoot开发的天猫商城源码

    前言 大家好,我是程序员it分享师,应粉丝的要求,今天给大家带来一个基于Springboot开发的天猫商城的源码! 使用技术 天猫商城系统使用的是Spring,SpringMvc,SpringBoot ...

  8. 基于springboot+mybatis+jsp日用品商城管理系统

    基于springboot+mybatis+jsp日用品商城管理系统 一.系统介绍 二.功能展示 1.主页(客户) 2.登陆.注册(客户) 3.我的购物车(客户) 4.我的订单(客户) 5.我的商铺(商 ...

  9. 基于springboot的仿天猫商城

    基于springboot的仿天猫商城 简介 迷你天猫商城是一个基于SSM框架的综合性B2C电商平台,需求设计主要参考天猫商城的购物流程:用户从注册开始,到完成登录,浏览商品,加入购物车,进行下单,确认 ...

最新文章

  1. 【js】将json类型的数组或对象转为字符串
  2. 超图iServer发布一个示例3D场景
  3. Fiddler建好代理后,能连到手机,但手机不能上网了,求破有果
  4. 抓取dump的头文件
  5. 前端学习(95):ps基本操作与图片格式
  6. Ubuntu下基于Virtualenv构建Python开发环境
  7. gms签名不一致_第三方稳定不掉ios软件企业签名怎么买
  8. java 蓝桥杯算法训练 P1102
  9. squirrelmail+change_sqlpass 认证 问题
  10. count(1),count(*)与count(列名)到底有什么区别?
  11. css 自制一些小特效
  12. 给临时停车号码牌插上翅膀:lua脚本语言加入—鲁哇客智能挪车号码牌技术升级之路
  13. UNIX环境高级编程 - UNIX基础知识
  14. 点评Hack易支付 - 免签约支付平台 -彩虹易支付,1分钟快速接入支付功能
  15. 敏捷团队要有一个《伊凡卡目标》——计划会的共识和每日站会的焦点
  16. 堡垒主机有什么用?看了这篇博客你就懂了。
  17. 你的团队需要一个会讲故事的人读书笔记
  18. win8右下角网络图标不见了_win8系统右下角的音量图标不见了的具体办法
  19. 嵌入式(十四)——Makefile编写及多级目录
  20. win10网上邻居看不到别的共享电脑怎么样办

热门文章

  1. 同步锁有哪些和同步锁的作用
  2. NTL之多项式模块GF2X
  3. 如何使用Elementor和OceanWP创建WordPress网站
  4. 汇编语言的建立、写、读文件
  5. 国二c语言优秀篇,2021c语言论文(优秀论文推荐8篇)范文1.pdf
  6. Google Chrome 检查更新时出错:无法启动更新检查(错误代码为 4: 0x80070005 -- system level)
  7. html设置按钮阴影效果,CSS如何设置文本和元素阴影效果?(代码示例)
  8. MySQL 服务无法启动如何解决
  9. android socketio,如何将Android应用程序连接到pythonsocketio后端?
  10. 去掉iphone手机数字默认下划线