【卖淘乐回收系统】源码springboot实战项目整套实现

发布于:2023-01-21 ⋅ 阅读:(415) ⋅ 点赞:(0)

卖淘乐项目源码解析
在这里插入图片描述

一、详细设计说明🍑

根据需求文档针对每个功能进行实现流程的设计

数据库的设计:
在这里插入图片描述

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
      在这里插入图片描述
      卖淘乐项目源码解析,喜欢的可以关注哦~

网站公告

今日签到

点亮在社区的每一天
去签到

热门文章