基于springboot框架的电脑商城项目(四)

这篇具有很好参考价值的文章主要介绍了基于springboot框架的电脑商城项目(四)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🎁🎁静态资源及sql文件分享
链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr
提取码:23gr

新增收货地址

(一)新建数据库

在store数据库中创建t_address表

CREATE TABLE t_address (
	aid INT AUTO_INCREMENT COMMENT '收货地址id',
	uid INT COMMENT '归属的用户id',
	name VARCHAR(20) COMMENT '收货人姓名',
	province_name VARCHAR(15) COMMENT '省-名称',
	province_code CHAR(6) COMMENT '省-行政代号',
	city_name VARCHAR(15) COMMENT '市-名称',
	city_code CHAR(6) COMMENT '市-行政代号',
	area_name VARCHAR(15) COMMENT '区-名称',
	area_code CHAR(6) COMMENT '区-行政代号',
	zip CHAR(6) COMMENT '邮政编码',
	address VARCHAR(50) COMMENT '详细地址',
	phone VARCHAR(20) COMMENT '手机',
	tel VARCHAR(20) COMMENT '固话',
	tag VARCHAR(6) COMMENT '标签',
	is_default INT COMMENT '是否默认:0-不默认,1-默认',
	created_user VARCHAR(20) COMMENT '创建人',
	created_time DATETIME COMMENT '创建时间',
	modified_user VARCHAR(20) COMMENT '修改人',
	modified_time DATETIME COMMENT '修改时间',
	PRIMARY KEY (aid)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

(二)收货地址实体类

在entity包下创建实体类Address继承baseEntity类

/**收货地址额实体类*/
public class Address extends BaseEntity {
    private Integer aid;
    private Integer uid;
    private String name;
    private String provinceName;
    private String provinceCode;
    private String cityName;
    private String cityCode;
    private String areaName;
    private String areaCode;
    private String zip;
    private String address;
    private String phone;
    private String tel;
    private String tag;
    private Integer isDefault;
 /**
 * get,set
 * equals和hashCode
 * toString
 */
}

(三)新增收货地址(持久层)

1.规划sql

1.新增收货地址对应的是插入语句:

insert into t_address (aid以外的所有字段) values (字段值)

2.大部分平台都会规定一个用户的收货地址数量,这里规定最多20个.那么在插入用户新的地址之前就要先做查询操作.如果查询到的是刚好20,这并不是一个java语法的异常,可以认为是业务控制的异常,这个异常随后在service抛,在controller捕获

select count(*) from t_address where uid=?
2.设计接口和抽象方法

创建接口AddressMapper,在这个接口中定义上面两个SQL语句抽象方法定义

public interface AddressMapper {
    //新增地址
    Integer insert(Address address);
//统计总地址
    Integer countByUid(Integer uid);
}

创建一个AddressMapper的映射文件,在这个文件中添加抽象方法映射到sql上

    <resultMap id="AddressEntityMap" type="com.cy.store.entity.Address">
        <id column="aid" property="aid"/>
        <result column="province_name" property="provinceName"/>
        <result column="province_code" property="provinceCode"/>
        <result column="city_name"   property="cityName"/>
        <result column="city_code" property="cityCode"/>
        <result column="area_name" property="areaName"/>
        <result column="area_code" property="areaCode"/>
        <result column="is_default" property="isDefault"/>
        <result column="created_user" property="createdUser"/>
        <result column="created_time" property="createdTime"/>
        <result column="modified_user" property="modifiedUser"/>
        <result column="modified_time" property="modifiedTime"/>
    </resultMap>

<insert id="insert" useGeneratedKeys="true" keyProperty="aid">
    INSERT INTO t_address (
        uid, name, province_name, province_code, city_name, city_code, area_name, area_code, zip,
        address, phone, tel,tag, is_default, created_user, created_time, modified_user, modified_time
    ) VALUES (
                 #{uid}, #{name}, #{provinceName}, #{provinceCode}, #{cityName}, #{cityCode}, #{areaName},
                 #{areaCode}, #{zip}, #{address}, #{phone}, #{tel}, #{tag}, #{isDefault}, #{createdUser},
                 #{createdTime}, #{modifiedUser}, #{modifiedTime}
             )
</insert>
    
<select id="countByUid" resultType="java.lang.Integer">
select count(*) from t_address where uid=#{uid}
</select>

(四)新增收货地址(业务层)

1.规划异常

插入数据时用户不存在(被管理员误删等等),抛UsernameNotFoundException异常(已经有了,不需要重复创建)
插入数据时产生未知的异常InsertException(已经有了,不需要重复创建)
当用户插入的地址是第一条时,需要将当前地址作为默认收货地址
实现办法:如果查询到统计总数为0则将当前地址的is_default值设置为1
如果查询的结果>=20,这时需要抛出业务控制的异常AddressCountLimitException

/**收货地址总数超出限制的异常(20条)*/
public class AddressCountLimitException extends ServiceException {
    /**重写ServiceException的所有构造方法*/
}

2.设计接口和抽象方法及实现

1.创建一个IAddressService接口,在接口中定义业务的抽象方法

public interface IAddressService {
    //新增收货地址
void addNewAddress(Integer uid,String username,Address address);

}

2.创建一个AddressServiceImpl类实现接口中抽象方法

//实现方法
@Service
public class AddressServiceImpl implements IAddressService {
    @Resource
    private AddressMapper addressMapper;
    @Resource
    private UserMapper userMapper;
    //在配置文件application.properties中定义user.address.max-count=20
    @Value("${user.address.max-count}")
    private Integer maxCount;
    @Override
    public void addNewAddress(Integer uid, String username, Address address) {
        Integer count = addressMapper.countByUid(uid);
        if (count>=maxCount){
            throw new AddressCountLimitException("收货地址大于20条");
        }
        User user = userMapper.findUid(uid);
        if (user==null || user.getIsDelete()==1){
            throw new UsernameNotFoundException("用户未登录");
        }
         address.setUid(uid);
        Integer isDefault=count==0?1:0;
        address.setIsDefault(isDefault);
        address.setCreatedTime(new Date());
        address.setModifiedUser(username);
        address.setModifiedTime(new Date());
        address.setCreatedUser(username);
            Integer insert = addressMapper.insert(address);

        if (insert!=1){
            throw new InsertException("添加地址有错误");
        }

    }
}

(五)新增收货地址(控制层)

1.处理异常

业务层抛出了收货地址总数超出上限的异常,在BaseController中进行捕获处理

else if (e instanceof AddressCountLimitException) {
    result.setState(4003);
    result.setMessage("用户的收货地址超出上限的异常");
}
2.设计请求

请求路径:/addresses/add_new_address
请求方式:post
请求参数:Address address,HttpSession session
响应结果:JsonResult< Void>

3.处理请求

在controller包下创建AddressController并继承BaseController,该类用来处理用户收货地址的请求和响应。

@PostMapping("add_new_address")
    public JsonResult<Void> add(Address address, HttpSession session){
    Integer getuidfromsession = getuidfromsession(session);
    String getusernamesession = getusernamesession(session);
    addressService.addNewAddress(getuidfromsession,getusernamesession,address);
    return new JsonResult<>(ok);
}

(六)新增收货地址(前端页面)

        <script>
            $("#btn-add-new-address").click(function () {
                $.ajax({
                    url: "/addresses/add_new_address",
                    type: "POST",
                    data: $("#form-add-new-address").serialize(),
                    dataType: "JSON",
                    success: function (json) {
                        if (json.state == 200) {
                            alert("新增收货地址成功")
                        } else {
                            alert("新增收货地址失败")
                        }
                    },
                    error: function (xhr) {
                        alert("新增收货地址时产生未知的异常!"+xhr.message);
                    }
                });
            });
        </script>

获取省市区列表

新增收货地址页面的三个下拉列表的内容把这些数据保存到数据库中,用户点击下拉列表时相应的数据会被详细的展示出来,然后监听用户选择了哪一项以便后面的下拉列表进行二级关联

(一)新建数据库

1.创建t_dict_district表

CREATE TABLE t_dict_district (
  id INT(11) NOT NULL AUTO_INCREMENT,
  parent VARCHAR(6) DEFAULT NULL,
  `code` VARCHAR(6) DEFAULT NULL,
  `name` VARCHAR(16) DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

parent代表父区域的代码号
code代表自身的代码号
省的父代码号是+86,代表中国

向该表中插入省市区数据

LOCK TABLES t_dict_district WRITE;
INSERT INTO t_dict_district VALUES (1,'110100','110101','东城区'),(2,'110100','110102','西城区')等等等等;
UNLOCK TABLES;

(二)创建省市区的实体类

在包entity下创建实体类District(不需要继承BaseEntity,但因为没有继承BaseEntity所以需要实现接口Serializable序列化)

/**省市区的数据实体类*/
public class District implements Serializable {
    private Integer id;
    private String parent;
    private String code;
    private String name;
 /**
 * get,set
 * equals和hashCode
 * toString
 */
}

(三)获取省市区列表(持久层)

1.规划sql
select * from t_dict_district where parent=? order by ASC
2.设计接口和抽象方法

在mapper层下创建接口DistrictMapper

在这里插入代码片

(四)获取省市区列表(业务层)

1.设计接口和抽象方法及实现

1.创建一个接口IDistrictService,并定义抽象方法

public interface IDistrictService {

    /**
     * 根据父代码号来查询区域信息(省或市或区)
     * @param parent 父代码号
     * @return 多个区域的信息
     */
    List<District> getByParent(String parent);
}

2.创建DistrictServiceImpl实现类来实现抽象方法

@Service
public class DistrictServiceImpl implements IDistrictService {
    @Resource
    private DistrictMapper districtMapper;

    @Override
    public List<District> getByParent(String parent) {
        List<District> districtList = districtMapper.findByParent(parent);
        for (District d:
             districtList) {
            d.setParent(null);
            d.setId(null);
        }
        return districtList;
    }
}

(五)获取省市区列表(控制层)

1.设计请求

请求路径:/districts/
请求方式:GET
请求参数:String parent
响应结果:JsonResult<List< District>

2.处理请求
@RestController
@RequestMapping("districts")
public class DistrictController extends BaseController{

    @Autowired
    private IDistrictService districtService;
    @GetMapping({"/",""})
    public JsonResult<List<District>> getByParent(String parent){
        List<District> list = districtService.getByParent(parent);
        return new JsonResult<>(ok,list);
    }
}

**为了能不登录也可以访问该数据,需要将districts请求添加到白名单中:
在LoginInterceptorConfigure类的addInterceptors方法中添加代码:patterns.add(“/districts/ * *”); **

(六)获取省市区列表(前端页面)

1.原始的下拉列表展示是将数据放在js,再动态获取js中的数据,而目前为止我们已经将数据放在了数据库,所以不能让它再使用这种办法了,所以需要注释掉addAddress.html页面的这两行js代码:

<script type="text/javascript" src="../js/distpicker.data.js"></script>
<script type="text/javascript" src="../js/distpicker.js"></script>

获取省市区名称

(一)获取省市区名称(持久层)

1.规划sql

根据当前code来获取当前省市区的名称,对应就是一条查询语句

select * from t_dict_district where code=?
2.设计接口和抽象方法

在DistrictMapper接口定义findNameByCode方法

    //根据当前code来获取当前省市区的名称,对应就是一条查询语句
    List<District> findNameByCode(String code);

在DistrictMapper.xml文件中添加findNameByCode方法的映射

    <select id="findNameByCode" resultType="java.lang.String">
select * from t_dict_district where code=#{code}
      </select>

(二)获取省市区名称(业务层)

1.规划异常

没有异常需要处理

2.设计接口和抽象方法及实现

1.在IDistrictService接口定义对应的业务层接口中的抽象方法

//根据code查询
    String getNameByCode(String code);

2.在DistrictServiceImpl实现此方法

    @Override
    public String getNameByCode(String code) {
        String name = districtMapper.findNameByCode(code);
        return name;
    }

(三)获取省市区名称(控制层)

实际开发中在获取省市区名称时并不需要前端传控制层,然后传业务层,再传持久层,而是在新增收货地址的业务层需要获取省市区名称,也就是说获取省市区名称的模块不需要控制层,只是需要被新增收货地址的业务层所依赖.

(四)获取省市区名称(业务层优化)

1.添加地址层依赖于IDistrictService层

@Autowired
private IDistrictService districtService;

2.在AddressServiceImpl的方法中将DistrictService接口中获取到的省市区数据封装到address对象,(此时address就包含了所有用户收货地址的数据)

/**
* 对address对象中的数据进行补全:省市区的名字看前端代码发现前端传递过来的省市区的name分别为:
* provinceCode,cityCode,areaCode,所以这里可以用address对象的get方法获取这三个的数据
 */
String provinceName = districtService.getNameByCode(address.getProvinceCode());
String cityName = districtService.getNameByCode(address.getCityCode());
String areaName = districtService.getNameByCode(address.getAreaCode());
address.setProvinceName(provinceName);
address.setCityName(cityName);
address.setAreaName(areaName);

(五)获取省市区名称(前端页面)

在addAddress.html页面中来编写对应的省市区展示及根据用户的不同选择来限制对应的标签中的内容

            /**因为清空后下拉列表的select标签没有option标签,所以需要设置一个默认的option标
             * 签并给市,县加上该标签.option标签并不会把内容发送到后端,而是将value值发
             * 送给后端,所以用value表示当前这个区域的code值
             * */
            var defaultOption="<option value='0'>-----请选择-----</option>";
            $(document).ready(function () {
                //加载省的数据罗列时代码量较多,建议定义在外部方法中,然后在这里调用定义的方法
                showProvinceList();

                //将省,市,县的下拉列表内容设为"-----请选择-----"
                /**
                 * select标签默认获取第一个option的内容填充到下拉列表中,所以即使加载
                 * 页面时省区域的下拉列表中已经有了所有省但仍然会显示-----请选择-----
                 * */
                $("#province-list").append(defaultOption);

                $("#city-list").append(defaultOption);
                $("#area-list").append(defaultOption);
            });

            //省的下拉列表数据展示
            function showProvinceList() {
                $.ajax({
                    url: "/districts",//发送请求用于获取所有省对象
                    type: "POST",
                    data: "parent=86",
                    dataType: "JSON",
                    success: function (json) {
                        if (json.state == 200) {
                            var list = json.data;//获取所有省对象的List集合
                            for (var i = 0; i < list.length; i++) {
                                var opt =
                                    "<option value='"+list[i].code+"'>"+list[i].name+"</option>";
                                $("#province-list").append(opt);
                            }
                        } else {
                            <!--这个其实永远不会执行,因为没有编写
                            异常,控制层返回的状态码永远是OK-->
                            alert("省/直辖区的信息加载失败")
                        }
                    }
                    //这里没有写属性error,不知道为啥不用写,感觉写了更好
                });
            }

            /**
             * change()函数用于监听某个控件是否发生改变,一旦发生改变就
             * 会触发参数形式的函数,所以参数需要是function(){}
             * */
            $("#province-list").change(function () {
                //先获取到省区域父代码号
                var parent = $("#province-list").val();

                /*
                 * 将市,县下拉列表的所有option清除并显示内容-----请选择-----
                 * empty()表示某标签的所有子标签(针对此页面来说select的子标
                 * 签只有option)
                 * */
                $("#city-list").empty();
                $("#area-list").empty();
                //填充默认值:-----请选择-----
                $("#city-list").append(defaultOption);
                $("#area-list").append(defaultOption);

                if (parent == 0) {//如果继续程序,后面的ajax接收的json数据中的data是
                    return;//空集合[],进不了for循环,没有任何意义,所以直接在这里终止程序
                }
                $.ajax({
                    url: "/districts",
                    type: "POST",
                    data: "parent="+parent,
                    dataType: "JSON",
                    success: function (json) {
                        if (json.state == 200) {
                            var list = json.data;
                            for (var i = 0; i < list.length; i++) {
                                var opt =
                                    "<option value='"+list[i].code+"'>"+list[i].name+"</option>";
                                $("#city-list").append(opt);
                            }
                        } else {
                            alert("市的信息加载失败")
                        }
                    }
                });
            });

            $("#city-list").change(function () {
                var parent = $("#city-list").val();
                $("#area-list").empty();
                $("#area-list").append(defaultOption);

                if (parent == 0) {
                    return;
                }
                $.ajax({
                    url: "/districts",
                    type: "POST",
                    data: "parent="+parent,
                    dataType: "JSON",
                    success: function (json) {
                        if (json.state == 200) {
                            var list = json.data;
                            for (var i = 0; i < list.length; i++) {
                                var opt =
                                    "<option value='"+list[i].code+"'>"+list[i].name+"</option>";
                                $("#area-list").append(opt);
                            }
                        } else {
                            alert("县的信息加载失败")
                        }
                    }
                });
            });

后记
👉👉💕💕美好的一天,到此结束,下次继续努力!欲知后续,请看下回分解,写作不易,感谢大家的支持!! 🌹🌹🌹
文章来源地址https://www.toymoban.com/news/detail-436634.html

到了这里,关于基于springboot框架的电脑商城项目(四)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于springboot框架的电脑商城项目(八)

    🎁🎁静态资源及sql文件分享 链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr 提取码:23gr 1.规划sql 这里需要将商品表和购物车表进行连表查询 2.设计接口和抽象方法 在store包下创建一个vo包,在该包下面创建CartVO类,不需要继承BaseController类,那相应的就需要单独实现Serializa

    2024年02月05日
    浏览(43)
  • 基于springboot框架的电脑商城项目(九)

    🎁🎁静态资源及sql文件分享 链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr 提取码:23gr 1.规划sql 用户在购物车列表页中通过随机勾选相关的商品,在点击\\\"结算\\\"按钮后跳转到\\\"确认订单页\\\",在这个页面中需要展示用户在上个页面所勾选的\\\"购物车列表页\\\"中对应的数据.且展示

    2024年02月05日
    浏览(40)
  • 基于springboot框架的电脑商城项目(二)

    当用户输入用户名和密码将数据提交给后台数据库进行查询,如果存在对应的用户名和密码则表示登录成功,登录成功之后跳转到系统的主页就是index.html页面,跳转在前端使用jquery来完成。 1.规划sql语句 依据用户提交的用户名和密码做select查询。 2.设计接口和抽象方法 在

    2024年02月05日
    浏览(42)
  • 【五一创作】基于springboot框架的电脑商城项目(三)

    1.规划sql 根据用户id修改信息的SQL语句 根据用户id查询的sql语句 2.接口与抽象方法 更新用户的信息方法的定义 在UserMapper.xml文件中进行映射编写 设计两个功能: 1.当打开页面时显示当前登录的用户的信息 2.点击修改按钮时更新用户的信息 1.异常规划 点击个人资料页面时可能找

    2024年02月04日
    浏览(52)
  • Springboot+mysql+基于VUE框架的商城综合项目设计与实现 毕业设计-附源码111612

    基于VUE框架的商城综合项目设计与实现 随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,商城综合项目当然也不能排除在外。商城综合项目是以实际运用为开发背景,运用软件工程原理和开发方法,采用

    2024年02月01日
    浏览(65)
  • SpringBoot项目--电脑商城【上传头像】

    把文件存到数据库中,需要图片时访问数据库,数据库将文件解析为字节流返回,最后写到本地的某一个文件.这种方法太耗费资源和时间了 将对应的文件保存在操作系统上,然后再把这个 文件路径记录下 来,因为在记录路径的时候是非常便捷和方便的,将来如果要打开这个文件可以

    2024年02月09日
    浏览(40)
  • SpringBoot项目--电脑商城【确认订单】

    用户在购物车列表页中通过随机勾选相关的商品,在点击\\\"结算\\\"按钮后跳转到\\\"确认订单页\\\",在这个页面中需要展示用户在上个页面所勾选的\\\"购物车列表页\\\"中对应的数据.说白了也就是列表展示,且展示的内容还是来自于购物车表.但是用户勾选了哪些商品呢,所 以\\\"购物车列表页\\\"需

    2024年02月09日
    浏览(40)
  • SpringBoot项目--电脑商城【新增收货地址】

    t_address 注意name是,所以需要用`` 在entity包下创建实体类Address继承BaseEntity类 当前收货地址功能模块: 第一个页面:列表的展示,修改,删除,设置默认 第二个页面:新增收货地址 开发顺序:新增收货地址-列表的展示-设置默认收货地址-删除收货地址-修改收货地址 1.新增收货地

    2024年02月09日
    浏览(46)
  • SpringBoot项目实战笔记:电脑商城项目实战(SpringBoot+MyBatis+MySQL)

    花了一段实现刚学完SpringBoot,做个项目练练手。教程视频来源于B站。 视频链接: 【SpringBoot项目实战完整版】SpringBoot+MyBatis+MySQL电脑商城项目实战_哔哩哔哩_bilibili 目录 一、系统概述与环境搭建 1. 系统开发及运行环境 2.项目分析 3.创建项目 4.配置并运行项目 4.1 运行项目

    2024年02月12日
    浏览(42)
  • SpringBoot项目--电脑商城【加入购物车】

    1.使用use命令先选中store数据库 2.在store数据库中创建t_cart用户数据表 在entity包下创建购物车的Cart实体类并使其继承BaseEntity 1.向购物车表中插入商品数据的SQL语句 2.如果当前商品已经在购物车存在,则直接更新商品即可 3.在插入或者更新具体执行哪个语句,取决于数据库中是否

    2024年02月09日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包