🍁【卖淘乐回收系统】
卖淘乐项目源码解析
一、详细设计说明🍑
根据需求文档针对每个功能进行实现流程的设计
数据库的设计:
1.用户注册
1.首页点击注册跳转到注册页面regist.html
2.注册页面输入账号、密码…提交注册,将用户信息提交到控制器
3.控制器调用UserServiceImpl的addUser进行注册保存
- 首先根据用户名调用UserDAO查询当前用户信息,如果用户信息已经存在则直接提示用户名已经存在
- 如果用户名不存在则进行保存操作,返回保存结果
4.控制器获取注册结果,进行页面跳转:
- 如果注册失败,则跳转回注册页面并提示
- 如果注册成功,则跳转到登录页面提示注册成功,并显示账号
2.首页加载分类列表
同步实现(使用):
异步实现(对比):
3.点击分类联动显示品牌列表
4.品牌联动显示商品列表:(分页)
5.加载手机的评估项及选项
6.商品价格评估
7.用户登录+提交订单用户登录+提交订单
提交订单:
保存订单+生成订单:
8.项目maven聚合
二、首页分类列表加载🍑
🔥实现数据库操作
查询所有的分类信息(无需分页)
数据表分析:tb_category
创建实体类:
package com.qfedu.mtl.beans;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* @Description: 商品一级分类实体类
* @Author : Jerry
* @create : 2022-08-06 10:34
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Category {
private int categoryId;
private String categoryName;
private String categoryIcon;
private String categoryStatus;
}
创建DAO接口,定义操作方法:
package com.qfedu.mtl.dao;
import com.qfedu.mtl.beans.Category;
import java.util.List;
/**
* @Description: 定义一级分类的数据库操作
* @Author : Jerry
* @create : 2022-08-06 10:38
*/
public interface CategoryDAO {
public List<Category> selectCategories();
}
创建并配置映射文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace = 所需实现的接口全限定名-->
<mapper namespace="com.qfedu.mtl.dao.CategoryDAO">
<resultMap id="categoryMap" type="Category">
<id column="category_id" property="categoryId"/>
<result column="category_name" property="categoryName"/>
<result column="category_icon" property="categoryIcon"/>
<result column="category_status" property="categoryStatus"/>
</resultMap>
<select id="selectCategories" resultMap="categoryMap">
select category_id,category_name,category_icon,category_status
from tb_category
where category_status=1
</select>
</mapper>
🔥业务逻辑层实现:
创建service接口:
package com.qfedu.mtl.service;
import com.qfedu.mtl.beans.Category;
import java.util.List;
/**
* @Description: 一级分类业务接口
* @Author : Jerry
* @create : 2022-08-06 10:48
*/
public interface CategoryService {
public List<Category> listCategories();
}
实现类:
package com.qfedu.mtl.service.impl;
import com.qfedu.mtl.beans.Category;
import com.qfedu.mtl.dao.CategoryDAO;
import com.qfedu.mtl.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Description: 一级分类业务实现类
* @Author : Jerry
* @create : 2022-08-06 10:49
*/
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
private CategoryDAO categoryDAO;
@Override
public List<Category> listCategories() {
List<Category> categoryList = categoryDAO.selectCategories();
return categoryList;
}
}
🔥IndexController实现
package com.qfedu.mtl.controlller;
import com.qfedu.mtl.beans.Category;
import com.qfedu.mtl.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-06 11:16
*/
@Controller
@RequestMapping("/index")
public class IndexController {
@Autowired
private CategoryService categoryService;
@RequestMapping("/index.html")
public String loadCategory(Model model){
List<Category> categoryList = categoryService.listCategories();
model.addAttribute("categoryList",categoryList);
return "index";
}
}
三、分类联动显示品牌列表🍑
功能说明:在首页点击一级分类,动态显示当前一级分类下的品牌列表
🔥数据库操作实现
根据一级分类ID查询当前分类下的所有品牌
数据表分析
SQL语句:
select brand_id,brand_name,brand_logo,brand_desc,create_time,brand_status
from tb_brand b inner join tb_category_brand cb
on b.brand_id = cb.fk_brand_id
where cb.fk_category_id=1 and b.brand_status=1
创建实体类
package com.qfedu.mtl.beans;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.io.Serializable;
import java.util.Date;
/**
* @Description: 品牌实体类
* @Author : Jerry
* @create : 2022-08-06 16:57
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Brand implements Serializable {
private int brandId;
private String brandName;
private String brandLogo;
private String brandDesc;
private Date brandCreateTime;
private int brandStatus;
}
创建DAO接口
package com.qfedu.mtl.dao;
import com.qfedu.mtl.beans.Brand;
import java.util.List;
/**
* @Description: 品牌信息的数据库操作
* @Author : Jerry
* @create : 2022-08-06 17:22
*/
public interface BrandDAO {
public List<Brand> selectBrandByCategoryId(int categoryId);
}
配置映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace = 所需实现的接口全限定名-->
<mapper namespace="com.qfedu.mtl.dao.BrandDAO">
<resultMap id="brandMap" type="Brand">
<id column="brand_id" property="brandId"/>
<result column="brand_name" property="brandName"/>
<result column="brand_logo" property="brandLogo"/>
<result column="brand_desc" property="brandDesc"/>
<result column="create_time" property="brandCreateTime"/>
<result column="brand_status" property="brandStatus"/>
</resultMap>
<select id="selectBrandByCategoryId" resultMap="brandMap">
select brand_id,brand_name,brand_logo,brand_desc,create_time,brand_status
from tb_brand b inner join tb_category_brand cb
on b.brand_id = cb.fk_brand_id
where cb.fk_category_id=#{categoryId} and b.brand_status=1
</select>
</mapper>
🔥业务逻辑层实现
BrandService接口:
package com.qfedu.mtl.service;
import com.qfedu.mtl.beans.Brand;
import java.util.List;
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-07 10:26
*/
public interface BrandService {
public List<Brand> listBrandByCategoryId(int categoryId);
}
实现类:
package com.qfedu.mtl.service.impl;
import com.qfedu.mtl.beans.Brand;
import com.qfedu.mtl.dao.BrandDAO;
import com.qfedu.mtl.service.BrandService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Description: 品牌业务实现
* @Author : Jerry
* @create : 2022-08-07 10:28
*/
@Service
public class BrandServiceImpl implements BrandService {
@Autowired
private BrandDAO brandDAO;
@Override
public List<Brand> listBrandByCategoryId(int categoryId) {
return brandDAO.selectBrandByCategoryId(categoryId);
}
}
🔥控制层实现
控制器方法参数如果是简单类型,请使用对应的封装类
针对处理异步请求的方法,返回的数据需要封装状态码和数据
package com.qfedu.mtl.controlller;
import com.qfedu.mtl.beans.Brand;
import com.qfedu.mtl.service.BrandService;
import com.qfedu.mtl.vo.StatusVO;
import com.qfedu.mtl.vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-07 10:33
*/
@Controller
@RequestMapping("/brand")
public class BrandController {
@Autowired
private BrandService brandService;
//控制器方法参数如果是简单类型,请使用对应的封装类
//针对处理异步请求的方法,返回的数据需要封装状态码和数据
@ResponseBody
@RequestMapping("/list")
public R list(@RequestParam(defaultValue = "0") Integer categoryId){
List<Brand> brandList = brandService.listBrandByCategoryId(categoryId);
R r = new R(StatusVO.SUCCESS_CODE, "success", brandList);
return r;
}
}
🔥R封装:
package com.qfedu.mtl.vo;
import lombok.Data;
import lombok.ToString;
import java.util.List;
/**
* @Description: 相应异步请求的VO类
* @Author : Jerry
* @create : 2022-08-07 11:34
*/
@Data
@ToString
public class R<T> {
private int code;
private String msg;
private Object data;
public R(int code,String msg){
this.code = code;
this.msg = msg;
}
public R(int code,String msg,Object data){
this.code = code;
this.msg = msg;
this.data = data;
}
}
四、品牌联动显示商品列表🍑
当点击品牌列表中的某个品牌时,查询这个品牌下对应的商品信息
🔥数据库操作实现:
- 根据品牌ID分页查询商品信息
- 根据品牌ID查询商品总数
数据表分析
SQL实现:
--根据品牌ID,分页查询当前品牌下的商品信息
select good_id,good_name,good_img,good_cost,good_min_price
from tb_good g inner join tb_brand_good bg
on g.good_id = bg.fk_good_id
where bg.fk_brand_id = 1 limit 0,8
--根据品牌ID查询商品总数
select count(1)
from tb_good g inner join tb_brand_good bg
on g.good_id = bg.fk_good_id
where bg.fk_brand_id = 1
创建实体类:
package com.qfedu.mtl.beans;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* @Description: 商品实体类
* @Author : Jerry
* @create : 2022-08-07 16:18
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Goods {
private int goodId;
private String goodName;
private String goodImg;
//价格 在程序处理及数据库存储中使用int类型,单位为分
private int goodCost;
private int goodMinPrice;
// private int goodFirstPrice;
// private int goodSecondPrice;
// private int goodThirdPrice;
// private int goodForthPrice;
// private int goodFifthPrice;
}
创建DAO接口:
package com.qfedu.mtl.dao;
import com.qfedu.mtl.beans.Goods;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @Description: 完成商品信息的数据库操作
* @Author : Jerry
* @create : 2022-08-07 16:25
*/
public interface GoodsDAO {
public List<Goods> selectGoodsByBrandIdWithPage(@Param("brandId") int brandId,
@Param("start") int start,
@Param("limit") int limit);
public int selectCountByBrandId(int brandId);
}
配置映射文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace = 所需实现的接口全限定名-->
<mapper namespace="">
<resultMap id="goodsMap" type="Goods">
<id column="good_Id" property="goodsId"/>
<result column="good_name" property="goodsName"/>
<result column="good_img" property="goodsImg"/>
<result column="good_cost" property="goodsCost"/>
<result column="good_min_price" property="goodsMinPrice"/>
</resultMap>
<select id="selectGoodsByBrandIdWithPage" resultMap="goodsMap">
select good_id,good_name,good_img,good_cost,good_min_price
from tb_good g inner join tb_brand_good bg
on g.good_id = bg.fk_good_id
where bg.fk_brand_id = #{brandId} limit #{start},#{limit}
</select>
<select id="selectCountByBrandId" resultType="int">
select count(1)
from tb_good g inner join tb_brand_good bg
on g.good_id = bg.fk_good_id
where bg.fk_brand_id = #{brandId}
</select>
</mapper>
🔥创建分页帮助类
package com.qfedu.mtl.util;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.List;
/**
* @Description: 分页帮助类
* @Author : Jerry
* @create : 2022-08-07 16:42
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class PageInfo<T> {
private int pageNum;
private int pageCount;
private int count;
private int prePage;
private int nextPage;
private List<T> list;
public static final int PAGE_SIZE=8;
}
🔥业务逻辑层实现:
GoodsService接口:
package com.qfedu.mtl.service;
import com.qfedu.mtl.beans.Goods;
import com.qfedu.mtl.util.PageInfo;
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-07 16:39
*/
public interface GoodsService {
public PageInfo<Goods> listGoodsByBrandId(int brandId,int pageNum);
}
package com.qfedu.mtl.service;
import com.qfedu.mtl.beans.Goods;
import com.qfedu.mtl.util.PageInfo;
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-07 16:39
*/
public interface GoodsService {
public PageInfo<Goods> listGoodsByBrandId(int brandId,int pageNum);
}
实现类:
package com.qfedu.mtl.service.impl;
import com.qfedu.mtl.beans.Goods;
import com.qfedu.mtl.dao.GoodsDAO;
import com.qfedu.mtl.service.GoodsService;
import com.qfedu.mtl.util.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Description: 商品业务实现类
* @Author : Jerry
* @create : 2022-08-07 16:52
*/
@Service
public class GoodsServiceImpl implements GoodsService {
@Autowired
private GoodsDAO goodsDAO;
@Override
public PageInfo<Goods> listGoodsByBrandId(int brandId, int pageNum) {
int start = (pageNum -1)*PageInfo.PAGE_SIZE;
int limit = PageInfo.PAGE_SIZE;
List<Goods> goodsList = goodsDAO.selectGoodsByBrandIdWithPage(brandId, start, limit);
int count = goodsDAO.selectCountByBrandId(brandId);
int pageCount = count%limit == 0 ? count/limit : count/limit+1;
int prePage = pageNum>1 ?pageNum-1 : 1;
int nextPage = pageNum < pageCount ?pageNum+1 : pageCount;
return new PageInfo<Goods>(pageNum,pageCount,count,prePage,nextPage,goodsList);
}
}
🔥GoodsController实现
package com.qfedu.mtl.controlller;
import com.qfedu.mtl.beans.Goods;
import com.qfedu.mtl.service.GoodsService;
import com.qfedu.mtl.util.PageInfo;
import com.qfedu.mtl.vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-07 17:17
*/
@Controller
@RequestMapping("/goods")
public class GoodsController {
@Autowired
private GoodsService goodsService;
/**
* 根据品牌ID查询商品信息
* @param brandId
* @param pageNum
* @return
*/
@ResponseBody
@RequestMapping("/listByBrand")
public R list(Integer brandId,@RequestParam(defaultValue = "1") Integer pageNum){
PageInfo<Goods> goodsPageInfo = goodsService.listGoodsByBrandId(brandId, pageNum);
R r = new R(0, "success", goodsPageInfo);
return r;
}
}
五、加载手机的评估项及选项🍑
当在首页点击对应型号的商品,跳转到评估页面(info.html)同时加载当前商品的评估项及选项。
🔥数据库操作:
- 根据商品ID查询商品信息
- 根据商品ID查询商品的评估项,关联查询评估项的选项
数据表分析:
SQL实现:
select
basic_info_id,basic_info_name,basic_info_status,basic_info_step,
info_detail_id,info_detail_name,info_detail_desc,
good_discount
form tb_good_detail gd inner join tb_info_detail d inner join tb_basic_info b
on gd.fk_info_detail_id = d.info_detail_id and d.fk_basic_info_id = b.basic_info_id
where gd.fk_good_id = #{goodsId} and b.basic_info_status = 1 and b.basic_info_step=#{step}
创建实体类:
- 评估项选项:
package com.qfedu.mtl.beans;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* @Description: 评估项的选项
* @Author : Jerry
* @create : 2022-08-08 11:51
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class InfoDetail {
private int infoDetailId;
private String infoDetailName;
private String infoDetailDesc;
}
- 评估项:
package com.qfedu.mtl.beans;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.List;
/**
* @Description: 商品评估项(评估类目)
* @Author : Jerry
* @create : 2022-08-08 11:50
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class BasicInfo {
private int basicInfoId;
private String basicInfoName;
private int basicInfoStatus;
private List<InfoDetail> infoDetailList;
}
修改评估项tb_basic_info数据表结构:
创建DAO接口:
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-08 14:34
*/
public interface BasicInfoDAO {
public List<BasicInfo> selectBasicInfosByGoodsId(@Param("goodsId") int goodsId,
@Param("step") int step);
}
配置映射文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace = 所需实现的接口全限定名-->
<mapper namespace="com.qfedu.mtl.dao.BasicInfoDAO">
<resultMap id="basicInfoMap" type="BasicInfo">
<id column="basic_info_id" property="basicInfoId"/>
<result column="basic_info_name" property="basicInfoName"/>
<result column="basic_info_status" property="basicInfoStatus"/>
<result column="basic_info_step" property="basicInfoStep"/>
<collection property="infoDetailList" ofType="InfoDetail">
<result column="info_detail_id" property="infoDetailId"/>
<result column="info_detail_name" property="infoDetailName"/>
<result column="info_detail_desc" property="infoDetailDesc"/>
</collection>
</resultMap>
<select id="selectBasicInfosByGoodsId" resultMap="basicInfoMap">
select
basic_info_id,basic_info_name,basic_info_status,basic_info_step,
info_detail_id,info_detail_name,info_detail_desc
form tb_good_detail gd inner join tb_info_detail d inner join tb_basic_info b
on gd.fk_info_detail_id = d.info_detail_id and d.fk_basic_info_id = b.basic_info_id
where gd.fk_good_id = #{goodsId} and b.basic_info_status = 1 and b.basic_info_step=#{step}
</select>
</mapper>
🔥业务逻辑层实现:
创建service接口,定义业务方法
/**
* @Description: 商品评论项业务处理
* @Author : Jerry
* @create : 2022-08-08 15:25
*/
public interface BasicInfoService {
public List<BasicInfo> listInfoByGoodsId(int goodsId,int step);
}
创建service实现类,实现业务方法:
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-08 15:27
*/
@Service
public class BasicInfoServiceImpl implements BasicInfoService {
@Autowired
private BasicInfoDAO basicInfoDAO;
@Override
public List<BasicInfo> listInfoByGoodsId(int goodsId, int step) {
List<BasicInfo> basicInfoList = basicInfoDAO.selectBasicInfosByGoodsId(goodsId, step);
return basicInfoList;
}
}
🔥BasicInfoController实现
package com.qfedu.mtl.controlller;
import com.qfedu.mtl.beans.BasicInfo;
import com.qfedu.mtl.beans.Goods;
import com.qfedu.mtl.service.BasicInfoService;
import com.qfedu.mtl.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-08 15:33
*/
@Controller
@RequestMapping("/basicInfo")
public class BasicInfoController {
@Autowired
private GoodsService goodsService;
@Autowired
private BasicInfoService basicInfoService;
@RequestMapping("/list")
public String list(Integer goodsId,Model model){
Goods goods = goodsService.getGoodsById(goodsId);
List<BasicInfo> step1List = basicInfoService.listInfoByGoodsId(goodsId, 1);
List<BasicInfo> step2List = basicInfoService.listInfoByGoodsId(goodsId, 2);
List<BasicInfo> step3List = basicInfoService.listInfoByGoodsId(goodsId, 3);
model.addAttribute("goods",goods);
model.addAttribute("step1List",step1List);
model.addAttribute("step2List",step2List);
model.addAttribute("step3List",step3List);
return "info";
}
}
六、商品价格评估🍑
当用户选择对应的选项之后,点击“查看价格”按钮,提交选项进行价格评估,显示最终价格。
🔥数据库操作实现
- 根据商品ID查询商品信息(最高回收价、最低价格)【已完成】
- 根据商品ID以及选中的选项ID统计扣除的金额
SQL实现:
select sun(good_discount)
from tb_good_detail
where fk_good_id=1 and fk_info_detail_id in (1,2,58)
创建InfoDetailDAO接口:
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-08 16:49
*/
public interface InfoDetailDAO {
// 1
// "1,3,58"
public int countPriceInfoDetails(@Param("goodsId") int goodsId,
@Param("ids") String ids);
}
配置映射文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace = 所需实现的接口全限定名-->
<mapper namespace="com.qfedu.mtl.dao.InfoDetailDAO">
<select id="countPriceInfoDetails" resultType="int">
select sun(good_discount)
from tb_good_detail
where fk_good_id= #{goodsId} and fk_info_detail_id in (${ids})
</select>
</mapper>
🔥Service业务流程实现
PriceCountservice接口:
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-08 17:10
*/
public interface PriceCountService {
public int countPrice(int goodsId, String ids);
}
实现类:
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-08 17:13
*/
@Service
public class PriceCountServiceImpl implements PriceCountService {
@Autowired
private GoodsDAO goodsDAO;
@Autowired
private InfoDetailDAO infoDetailDAO;
@Override
public int countPrice(int goodsId,String ids) {
Goods goods = goodsDAO.selectGoodsById(goodsId);
int price1 = infoDetailDAO.countPriceInfoDetails(goodsId, ids);//扣除的价格
int price2 = goods.getGoodsCost() - price1;
int price = price2<goods.getGoodsMinPrice()? goods.getGoodsMinPrice():price2;
price = price>goods.getGoodsCost()? goods.getGoodsCost():price;
return 0;
}
}
🔥PriceCountController实现
package com.qfedu.mtl.controlller;
import com.qfedu.mtl.beans.Goods;
import com.qfedu.mtl.service.GoodsService;
import com.qfedu.mtl.service.PriceCountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @Description: 计算价格的控制器
* @Author : Jerry
* @create : 2022-08-08 17:36
*/
@Controller
@RequestMapping("/price")
public class PriceCountController {
@Autowired
private PriceCountService priceCountService;
@Autowired
private GoodsService goodsService;
@RequestMapping("/count")
public String count(Integer goodsId, String property, String descId, Model model){
String ids = property + "," + descId;
Goods goods = goodsService.getGoodsById(goodsId);
int prices = priceCountService.countPrice(goodsId, ids);
//商品信息
model.addAttribute("goods", goods);
model.addAttribute("prices", prices);
model.addAttribute("ids", ids);
return "price";
}
}
七、用户登录校验🍑
🔥数据库操作实现
根据用户名查询用户信息
创建实体类:
/**
* @Description: 用户实体类
* @Author : Jerry
* @create : 2022-08-11 9:51
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
private int userId;
private String userName;
private String usePassword;
private String userSalt;
}
创建实体类的DAO:
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-11 10:02
*/
public interface UserDAO {
public User selectUserByUserName(String username);
}
配置映射文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace = 所需实现的接口全限定名-->
<mapper namespace="com.qfedu.mtl.dao.UserDAO">
<resultMap id="userMap" type="User">
<id column="user_id" property="userId"/>
<result column="user_name" property="userName"/>
<result column="user_password" property="userPassword"/>
<result column="user_salt" property="userSalt"/>
</resultMap>
<select id="selectUserByUserName" resultMap="userMap">
select user_id,user_name,user_password,user_salt
from tb_user
where user_name = #{userName}
</select>
</mapper>
🔥service业务逻辑层实现
UserService接口:
public interface UserService {
public User check(String userName,String userPwd);
}
实现类:
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserDAO userDAO;
@Override
public User check(String userName, String userPwd) {
User user = userDAO.selectUserByUserName(userName);
if(user !=null){
String md5 = MD5Utils.md5(userPwd + user.getUserSalt());
if(user.getUsePassword().equals(md5)){
return user;
}
}
return null;
}
}
🔥控制层实现
UserController:
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@Autowired
private CategoryService categoryService;
@RequestMapping("/login")
public String login(String userName, String userPwd, HttpServletRequest request){
User user = userService.check(userName,userPwd);
String pagePath = "login";
if(user == null){
request.setAttribute("tips","账户或密码错误!");
}else {
pagePath = "index";
HttpSession session = request.getSession();
session.setAttribute("user",user);
//因为跳转到index.html需要一级分类,因此在跳转之前需要传递一级分类集合
List<Category> categoryList = categoryService.listCategories();
request.setAttribute("categoryList",categoryList);
}
return pagePath;
}
}
🔥过滤器:
立即下单操作属于首先资源,也就是说用户只有在登录状态下才能下单,我们可以通过过滤器实现登录校验
@Component
@WebFilter("/*")
public class LoginFilter implements Filter {
private String[] excludePath = {"/","/index.html","/brand/list","/goods/listByBrand",
"/basicInfo/list","/price/count","/login.html",
"/user/login"};
private String[] excludeExts = {".jsp",".css",".js",".png"};
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//1.获取请求路径:
String uri = request.getRequestURI();
//2.如果此请求的路径是非受限资,则直接放行
boolean b = judge(uri);
if(b){
filterChain.doFilter(servletRequest,servletResponse);
}else{
//表示受限资源,需要验证是否登录
HttpSession session = request.getSession();
if(session.getAttribute("user") == null){
//未登录
request.setAttribute("tips","<label style = 'color:red'>请先登录!</label>");
request.getRequestDispatcher("/login.html").forward(request,response);
}else {
filterChain.doFilter(servletRequest,servletResponse);
}
}
}
private boolean judge(String path){
boolean flag = false;
for (String s:excludePath) {
if(s.equals(path)){
flag = false;
break;
}
}
for (String ext:excludePath) {
if(path.endsWith(ext)){
flag = false;
break;
}
}
return flag;
}
}
八、提交订单🍑
🔥立即下单:
在评估结果页面点击立即下单,查询商品评估详情跳转到订单提交页面
📕数据库实现:
根据商品评估时选择的选项ids查询选项及评估项信息
SQL实现:
select
basic_info_id,basic_info_name,basic_info_status,basic_info_step,
info_detail_id,info_detail_name,info_detail_desc,fk_basic_info_id
from tb_info_detail d inner join tb_basic_info b
on d.fk_basic_info_id = b.basic_info_id
where info_detail_id in (1,12,17,28)
在BasicInfoDAO中定义方法
public interface BasicInfoDAO {
//.....
public List<BasicInfo> selectInfoDetailsByIds(String ids);
}
配置映射文件:
<!--BaasicInfoMapper.xml-->
<select id="selectInfoDetailsByIds" resultMap="basicInfoMap">
select
basic_info_id,basic_info_name,basic_info_status,basic_info_step,
info_detail_id,info_detail_name,info_detail_desc,fk_basic_info_id
from tb_info_detail d inner join tb_basic_info b
on d.fk_basic_info_id = b.basic_info_id
where info_detail_id in (${ids})
</select>
📕业务逻辑层实现:
BasicInfoService接口:
public interface BasicInfoService {
//.....
/**
* 根据已经选中的选项id查询选项详情 以及选项对应的评估项
* @param ids
* @return
*/
public List<BasicInfo> listInfoDetailsByIds(String ids);
}
实现类:
@Service
public class BasicInfoServiceImpl implements BasicInfoService {
@Autowired
private BasicInfoDAO basicInfoDAO;
//.......
@Override
public List<BasicInfo> listInfoDetailsByIds(String ids) {
List<BasicInfo> basicInfoList = basicInfoDAO.selectInfoDetailsByIds(ids);
return basicInfoList;
}
}
OrderController实现:
@Controller
@RequestMapping("/order")
public class OrderController {
@Autowired
private BasicInfoService basicInfoService;
@RequestMapping("/create")
public String createOrder(Goods goods, Double price, String ids, Model model){
List<BasicInfo> basicInfoList = basicInfoService.listInfoDetailsByIds(ids);
model.addAttribute("goods", goods);
model.addAttribute("price", price);
model.addAttribute("basicInfoList", basicInfoList);
return "trade";
}
}
🔥保存订单
🔥生成订单
📕数据库操作实现:
- 保存订单信息:
- 保存订单的商品快照:
- 根据商品ID查询商品信息(√)
- 根据选择的选项ID查询选项详情(√)
添加字段:
创建实体类:
order:
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Order {
// order_id 订单编号
private int userId;
// user_id 用户ID
private String orderId;
// order_total_price 订单总价格
private int orderTotalPrice;
// user_addr 用户地址信息
private String userAddr;
// user_name 用户姓名
private String userName;
// user_tel 用户电话
private String userTel;
// create_time 订单创建时间
private Date createTime;
// order_desc 订单备注
private String orderDesc;
// retrieve_type 回收类型: 1 快递, 2 上门验收
private int retrieveType;
// order_status 订单状态:1 新订单,2 待指派,3 已指派,4 已完成,5 已关闭,6 用户已寄出,7 平台验收中,8 验收通过,9 待退回,10 已退回,11 用户已取消
private String payName;
private String payAccout;
private int orderStatus;
// send_logistics_name 寄送物流名称
private String sendLogisticsName;
// send_logistics_id 寄送物流单号
private String sendLogisticsId;
// order_processor 订单指派处理人
private String orderProcessor;
// back_text 退回原因
private String backText;
// back_logistics_name 退回物流名称
private String backLogisticsName;
// back_logistics_id 退回物流单号
private String backLogisticsId;
}
orderItem:
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class OrderItem {
private int itemId;
private String orderId;
private int goodsId;
private String goodsName;
private String goodsImg;
private String goodsInfo;
private int goodsPrice;
private int isComment;
}
创造DAO接口,定义操作方法:
OrderDAO:
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-11 16:48
*/
public interface OrderDAO {
public int insertOrder(Order order);
}
OrderItemDAO:
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-11 16:49
*/
public interface OrderItemDAO {
public int insertOrderItem(OrderItem orderItem);
}
配置映射文件:
orderMapper:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace = 所需实现的接口全限定名-->
<mapper namespace="com.qfedu.mtl.dao.OrderDAO">
<insert id="insertOrder">
insert into
tb_orders(order_id,user_id,order_total_price,user_addr,user_name,user_tel,create_time,order_desc,retrieve_type,order_status,pay_name,pay_account)
values(#{orderId},#{userId},#{orderTotalPrice},#{userAddr},#{userName},#{userTel},#{createTime},#{orderDesc},#{retrieveType},#{orderStatus},#{payName},#{payAccount})
</insert>
</mapper>
OrderItemMapper:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace = 所需实现的接口全限定名-->
<mapper namespace="com.qfedu.mtl.dao.OrderItemDAO">
<insert id="insertOrderItem">
insert into tb_order_items(order_id,good_id,good_name,good_img_path,good_info,good_price,is_comment)
values(#{orderId},#{goodsId},#{goodsName},#{goodsImg},#{goodsInfo},#{goodsPrice},#{isComment})
</insert>
</mapper>
📕业务逻辑层实现
orderService接口:
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-11 17:15
*/
public interface OrderService {
public String addOrder(Order order,int goodsId,String ids);
}
orderService实现类:
/**
* @Description:
* @Author : Jerry
* @create : 2022-08-11 17:17
*/
@Service
public class OrderServiceImpl implements OrderService{
@Autowired
private OrderDAO orderDAO;
@Autowired
private GoodsDAO goodsDAO;
@Autowired
private OrderItemDAO orderItemDAO;
@Autowired
private BasicInfoDAO basicInfoDAO;
@Transactional
public String addOrder(Order order, int goodsId, String ids) {
//1.生成订单编号(唯一性)
String orderId = UUID.randomUUID().toString().replace("-", "");
order.setOrderId(orderId);
order.setCreateTime(new Date());
//设置默认订单状态
// 快递:1待寄送,2已寄出,3待检测,--4待付款,5已完成
// --6待退回,7待退回签收,8已退回
// 上门:9待上门交易,5已完成
// 取消订单:10已取消
int orderStatus = order.getRetrieveType()==1?1:9;
order.setOrderStatus(orderStatus);
//2.保存订单
int i = orderDAO.insertOrder(order);
//3.保存快照
if(i>0){
Goods goods = goodsDAO.selectGoodsById(goodsId);
List<BasicInfo> basicInfoList = basicInfoDAO.selectInfoDetailsByIds(ids);
String goodsInfo = ""; // 颜色:白色 |
for(int m=0;m<basicInfoList.size();m++){
BasicInfo basicInfo = basicInfoList.get(m);
goodsInfo += basicInfo.getBasicInfoName() + ":";
List<InfoDetail> infoDetailList = basicInfo.getInfoDetailList();
for(int n = 0;n < infoDetailList.size();n++){
goodsInfo += infoDetailList.get(n).getInfoDetailName(); //配件:耳机、数据线 |
if(n< infoDetailList.size() -1){
goodsInfo += "、";
}else{
goodsInfo += " | ";
}
}
}
OrderItem orderItem = new OrderItem(0,orderId,goods.getGoodsId(),goods.getGoodsName(),
goods.getGoodsImg(),goodsInfo,order.getOrderTotalPrice(),0);
int j = orderItemDAO.insertOrderItem(orderItem);
if(j > 0){
return orderId;
}
}
return null;
}
}
📕控制层实现
@Controller
@RequestMapping("/order")
public class OrderController {
@Autowired
private BasicInfoService basicInfoService;
@Autowired
private OrderService orderService;
//......
@RequestMapping("/save")
public String saveOrder(Order order, Integer goodsId, String ids, HttpServletRequest request){
//获取当前登录的用户ID,存放到order中
User user = (User) request.getSession().getAttribute("user");
order.setUserId(user.getUserId());
String orderId = orderService.addOrder(order, goodsId, ids);
if(orderId!=null){
request.setAttribute("orderId",orderId);
request.setAttribute("tips","提交订单成功!");
}else {
request.setAttribute("tips","提交订单失败!");
}
return "order-tips";
}
}
九、项目打包部署🍑
🔥打包
将项目源码进行编译打包,形成一个可以部署在服务器运行的文件
- war包:SSM、JSP/Servlet
- jar包:spring boot
📕war包
pom.xml文件修改packing为war
执行mvn-package
在target目录下就会生成.war文件
📕 jar包
pom.xml文件修改packing为jar
执行mvn-package
在target目录下就会生成.jar文件pom.xml文件修改packing为jar
🔥部署
📕war包部署
- 安装JDK
- Tomcat
- 将war文件,拷贝粘贴到tomact_home/webapps
- 启动Tomcat
- 浏览器进行访问(项目的context-path默认为war文件名)
📕jar包部署
- 安装JDK
- 进入存放jar的目录,打开命令窗口
- java-jar***.jar
卖淘乐项目源码解析,喜欢的可以关注哦~
- java-jar***.jar