- 外星人商城项目介绍
- 项目背景
- 项目功能
- 项目技术
- 项目模块
- 项目要求
- 外星人商城项目开发流程
- 第一节 基础构建
- 第二节 用户注册
- 第三节 用户登录
- 第四节 用户管理
- 第一部分 密码修改
- 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
今天来完成新的模块
规划内容,编写sql语句
首先,查询用户是否存在
User findByUsername(String username);
Integer updatePasswordByUid(
@Param("uid") Integer uid,
@Param("password") String password,
@Param("modifiedUser") String modifiedUser,
@Param("modifiedTime") Date modifiedTime);
UPDATE
compution.t_user
SET
password = #{password},
modified_user = #{modifiedUser},
modified_time = #{modifiedTime}
WHERe
uid = #{uid}
2.修改密码-业务层
public void changePassword(Integer uid, String username, String oldPassword, String newPassword);
@Override
public void changePassword(Integer uid, String username, String oldPassword, String newPassword) {
// 调用userMapper的findByUid()方法,根据参数uid查询用户数据
User result = userMapper.findByUid(uid);
// 检查查询结果是否为null
if (result == null) {
// 是:抛出UserNotFoundException异常
throw new UserNotFoundException("用户数据不存在");
}
// 检查查询结果中的isDelete是否为1
if (result.getIsDelete().equals(1)) {
// 是:抛出UserNotFoundException异常
throw new UserNotFoundException("用户数据不存在");
}
// 从查询结果中取出盐值
String salt = result.getSalt();
// 将参数oldPassword结合盐值加密,得到oldMd5Password
String oldMd5Password = getMd5Password(oldPassword, salt);
// 判断查询结果中的password与oldMd5Password是否不一致
if (!result.getPassword().contentEquals(oldMd5Password)) {
// 是:抛出PasswordNotMatchException异常
throw new PasswordNotMatchException("原密码错误");
}
// 将参数newPassword结合盐值加密,得到newMd5Password
String newMd5Password = getMd5Password(newPassword, salt);
// 创建当前时间对象
Date now = new Date();
// 调用userMapper的updatePasswordByUid()更新密码,并获取返回值
Integer rows = userMapper.updatePasswordByUid(uid, newMd5Password, username, now);
// 判断以上返回的受影响行数是否不为1
if (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 getByUid(HttpSession session) {
// 从HttpSession对象中获取uid
Integer uid = getUidFromSession(session);
// 调用业务对象执行获取数据
User data = userService.getByUid(uid);
// 响应成功和数据
return new JsonResult(OK, data);
}
// public JsonResult4.修改密码-前端页面changePassword(String oldPassword, String newPassword, HttpSession session) { public String changePassword(String oldPassword, String newPassword, HttpSession session) { // 调用session.getAttribute("")获取uid和username Integer uid = getUidFromSession(session); String username = getUsernameFromSession(session); // 调用业务对象执行修改密码 userService.changePassword(uid, username, oldPassword, newPassword); // 返回成功 // return new JsonResult (OK); return "redirect:/web/login.html"; }
ajax
第二部分 个人资料 1. 个人资料-持久层
这里发现我对于mybatis中的判断这种不懂,需要回顾
UPDATE
compution.t_user
SET
phone = #{phone},
email = #{email},
gender = #{gender},
modified_user = #{modifiedUser},
modified_time = #{modifiedTime}
WHERe
uid = #{uid}
2. 个人资料-业务层
Integer updateInfoByUid(User user);
@Override
public void changeInfo(Integer uid, String username, User user) {
// 调用userMapper的findByUid()方法,根据参数uid查询用户数据
User result = userMapper.findByUid(uid);
// 判断查询结果是否为null
if (result == null) {
// 是:抛出UserNotFoundException异常
throw new UserNotFoundException("用户数据不存在");
}
// 判断查询结果中的isDelete是否为1
if (result.getIsDelete().equals(1)) {
// 是:抛出UserNotFoundException异常
throw new UserNotFoundException("用户数据不存在");
}
// 向参数user中补全数据:uid
user.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);
// 判断以上返回的受影响行数是否不为1
if (rows != 1) {
// 是:抛出UpdateException异常
throw new UpdateException("更新用户数据时出现未知错误,请联系系统管理员");
}
}
3. 个人资料-控制层
这里要进行异常处理
} else if (e instanceof UpdateException) {
result.setState(5001);
@RequestMapping("change_info")
public JsonResult changeInfo(User user, HttpSession session) {
// 从HttpSession对象中获取uid和username
Integer uid = getUidFromSession(session);
String username = getUsernameFromSession(session);
// 调用业务对象执行修改用户资料
userService.changeInfo(uid, username, user);
// 响应成功
return new JsonResult(OK);
}
4. 个人资料-前端页面
第三部分 上传头像 1. 上传头像-持久层
老样子,接口和sql语句
Integer updateAvatarByUid(
@Param("uid") Integer uid,
@Param("avatar") String avatar,
@Param("modifiedUser") String modifiedUser,
@Param("modifiedTime") Date modifiedTime);
UPDATE
compution.t_user
SET
avatar = #{avatar},
modified_user = #{modifiedUser},
modified_time = #{modifiedTime}
WHERe
uid = #{uid}
2. 上传头像-业务层
avatar:/upload/9c8dacd6-9f73-4c60-87ad-270eba65f24c.png
void changeAvatar(Integer uid, String username, String avatar);
@Override
public void changeAvatar(Integer uid, String username, String avatar) {
// 调用userMapper的findByUid()方法,根据参数uid查询用户数据
User result = userMapper.findByUid(uid);
// 检查查询结果是否为null
if (result == null) {
// 是:抛出UserNotFoundException
throw new UserNotFoundException("用户数据不存在");
}
// 检查查询结果中的isDelete是否为1
if (result.getIsDelete().equals(1)) {
// 是:抛出UserNotFoundException
throw new UserNotFoundException("用户数据不存在");
}
// 创建当前时间对象
Date now = new Date();
// 调用userMapper的updateAvatarByUid()方法执行更新,并获取返回值
Integer rows = userMapper.updateAvatarByUid(uid, avatar, username, now);
// 判断以上返回的受影响行数是否不为1
if (rows != 1) {
// 是:抛出UpdateException
throw new UpdateException("更新用户数据时出现未知错误,请联系系统管理员");
}
}
3. 上传头像-控制层
@PostMapping("change_avatar")
public JsonResult 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;若不包含该元素,返回结果为false
if (!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和username
Integer uid = getUidFromSession(session);
String username = getUsernameFromSession(session);
// 将头像写入到数据库中
userService.changeAvatar(uid, username, avatar);
// 返回成功头像路径
return new JsonResult(OK, avatar);
}
4. 上传头像-前端页面
第五节 热销商品 第六节 购物车
第一部分 加入购物车
第二部分 显示购物车
第三部分 购物车商品数量
第四部分 勾选数据


