SpringBoot电脑商城项目--修改默认收货地址

1. 修改默认收货地址-持久层

1.1 规划sql语句

  • 检测当前用户向设置为默认收货地址的这条数据是否存在

SELECT * FROM t_address WHERE aid=#{aid}

  • 在修改用户的收获默认地址之前,先将所有的收货地址设置为非默认

UPDATE t_address SET is_default=0 WHERE uid=#{uid}

  • 将用户当前选中的这条记录设置为默认收货地址

 UPDATE t_address SET is_default=1,
            modified_user=#{modifiedUser},
             modified_time=#{modifiedTime}
        WHERE aid=#{aid}

1.2 AddressMapper接口定义抽象方法

    /*** 根据aid查询收货地址数据* @param aid 收货地址id* @return*/Address findByAid(Integer aid);/*** 根据aid修改收货地址数据为默认地址* @param uid 用户id* @return*/Integer updateNonDefault(Integer uid);/*** 根据aid修改收货地址数据* @param * @return*/Integer updateDefaultByAid(@Param("aid") Integer aid,@Param("modifiedUser") String modifiedUser,@Param("modifiedTime") Date modifiedTime);

1.3 编写xml文件的sql映射

<select id="findByAid" resultMap="AddressEntityMap">SELECT * FROM t_address WHERE aid=#{aid}</select>
<!--    把用户的所有收货地址均设为0  --><update id="updateNonDefault">UPDATE t_address SET is_default=0 WHERE uid=#{uid}</update>
<!--    将选中的地址设置为 1      --><update id="updateDefaultByAid">UPDATE t_address SET is_default=1,modified_user=#{modifiedUser},modified_time=#{modifiedTime}WHERE aid=#{aid}</update>

1.4 进行测试

        在AddressMapperTest测试类中进行mapper接口测试

@Testvoid findByAid() {Address address = addressMapper.findByAid(7);System.out.println(address);}@Testvoid updateNonDefault() {Integer integer = addressMapper.updateNonDefault(1);System.out.println(integer);}@Testvoid updateDefaultByAid() {Integer integer = addressMapper.updateDefaultByAid(7, "admin", new Date());System.out.println(integer);}

2. 修改默认收货地址-业务层

2.1 异常规划

  • 在执行更新时产生未知的UpdateException异常,这个异常之前已经创建过了,无需重新创建
  • 访问的数据不是当前登录用户的收货地址数据,非法访问异常,AccessDeniedException异常

/**非法访问的异常*/
public class AccessDeniedException extends ServiceException {public AccessDeniedException() {super();}public AccessDeniedException(String message) {super(message);}public AccessDeniedException(String message, Throwable cause) {super(message, cause);}public AccessDeniedException(Throwable cause) {super(cause);}protected AccessDeniedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}
  • 收货地址有可能不存在的异常,AddressNotFoundException异常
package com.cy.store.service.ex;/**收货地址数据不存在的异常*/
public class AddressNotFoundException extends ServiceException {public AddressNotFoundException() {super();}public AddressNotFoundException(String message) {super(message);}public AddressNotFoundException(String message, Throwable cause) {super(message, cause);}public AddressNotFoundException(Throwable cause) {super(cause);}protected AddressNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}

2.2 接口类编写抽象方法

    /*** 设置默认收货地址* @param aid 收货地址id* @param uid 用户id* @param username 用户名*/void setDefault(Integer aid, Integer uid, String username);

2.3 实现类实现接口,重写抽象方法

    /*** 设置默认收货地址* @param aid 收货地址id* @param uid 用户id* @param username 用户名*/@Overridepublic void setDefault(Integer aid, Integer uid, String username) {
//        获取当前收货地址数据Address address = addressMapper.findByAid(aid);
//        判断用户id与收货地址数据中的用户id是否相同if (!address.getUid().equals(uid)){
//            不同的话抛出异常throw new AccessDeniedException("非法数据访问");}
//        将用户的所有收货地址的is_default字段设置为0Integer rows = addressMapper.updateNonDefault(uid);
//        一个用户可能有多个收货地址,因此可能返回的行数小于1说明异常if (rows<1){throw new UpdateException("更新数据时产生未知的异常");}
//        修改当前收货地址的is_default字段设置为1Integer integer = addressMapper.updateDefaultByAid(aid, username, new Date());if (integer!=1){throw new UpdateException("更新数据时产生未知的异常");}}

    2.4 AddressServiceTest测试类进行测试

        @Testvoid updateDefault() {addressService.setDefault(6,9,"admin");}

            数据库修改成功✌

     

    3. 修改默认收货地址-控制层

    3.1 在BaseController捕获异常

    
    /*** 控制层基类*/
    public class BaseController {//操作成功的状态码public static final int OK = 200;/*** 全局异常处理器,用于捕获并处理业务层抛出的异常。** @param e 捕获的异常对象* @return 返回封装后的 JsonResult 对象,包含状态码和错误信息*/
    //    该项目中产生了异常,会被统一拦截到此方法中,这个方法此时就充当了请求处理方法,方法的返回值直接给前端浏览器,返回给前端的数据中,状态码,状态码对应信息,数据@ExceptionHandler({ServiceException.class, FileUploadException.class})public JsonResult<Void> handleException(Throwable e) {// 创建一个 JsonResult 实例,并初始化异常消息JsonResult<Void> result = new JsonResult<>(e);// 判断异常类型,设置对应的状态码和提示信息if (e instanceof UsernameDuplicatedException){// 用户名被占用时返回 400 状态码和相应提示result.setState(4000);result.setMessage("用户名被占用");} else if (e instanceof InsertException){// 插入数据失败时返回 500 状态码和相应提示result.setState(4000);result.setMessage("注册时产生未知的异常");}else if (e instanceof UsernameNotFoundException){result.setState(4001);result.setMessage("用户数据不存在");}else if (e instanceof PasswordNotMatchException){result.setState(4002);result.setMessage("用户密码错误");}else if (e instanceof AddressCountLimitException){result.setState(4003);result.setMessage("收货地址超出上限");}else if (e instanceof AccessDeniedException){result.setState(4004);result.setMessage("收货地址数据非法访问");}else if (e instanceof AddressNotFoundException){result.setState(4005);result.setMessage("收货地址数据不存在");}else if (e instanceof UpdateException){result.setState(5003);result.setMessage("更新数据时产生未知的异常");} else if (e instanceof FileEmptyException) {result.setState(6000);} else if (e instanceof FileSizeException) {result.setState(6001);} else if (e instanceof FileTypeException) {result.setState(6002);} else if (e instanceof FileStateException) {result.setState(6003);} else if (e instanceof FileUploadIOException) {result.setState(6004);}// 返回最终的响应结果return result;}/*** 从Session中获取当前登录用户的uid* * @param session HttpSession对象,用于获取会话中的用户ID* @return 当前登录用户的uid* * `protected` 表示该方法只能被同一个包内的类或子类访问。* `final` 表示该方法不能被子类重写。*/protected final Integer getUidFromSession(HttpSession session) {// 从Session中获取uid// 从会话中获取uid属性并转换为整数类型返回return Integer.valueOf(session.getAttribute("uid").toString());}/*** 从Session中获取当前登录用户的用户名* @param session HttpSession对象,用于获取会话中的用户名* @return 当前登录用户的用户名*/protected final String getUsernameFromSession(HttpSession session) {// 从Session中获取当前登录的用户名return session.getAttribute("username").toString();}}
    

    3.2 设计请求

    /addresses/setDefault/{aid}

    @PathVariable("aid") Integer aid,HttpSession session

    GET

    JsonResult<Void>

    3.3 AddressController类编写业务代码

        /*** 设置默认收货地址* @param aid 收货地址id* @param session 当前登录的用户的会话* @return*/@RequestMapping("/setDefault/{aid}")public JsonResult<Void> setDefault(@PathVariable("aid") Integer aid, HttpSession session){Integer uid = getUidFromSession(session);String username = getUsernameFromSession(session);addressService.setDefault(aid,uid,username);return new JsonResult<>(OK);}

    3.4 测试

            先登录,访问localhost:8080/addresses/setDefault/7查看返回状态码

            数据库也修改成功✌

    4. 修改默认收货地址-前端页面

    41. address.html绑定点击事件

            首先需要先将之前展示的收货地址列表清空 $("#address-list").empty();然后优化一下展示收货地址列表的函数,创建一个点击事件,将收货地址id封装到点击事件上

    4.2 发送请求

    function setDefault(aid) {$.ajax({url: "/addresses/default/"+ aid,type: "POST",dataType: "json",success: function (json) {if (json.state == 200) {alert("设置默认地址成功")//	重新调用获取列表的方法showAddressList();}else{alert("设置默认地址失败")}},error: function (xhr) {alert("设置默认地址失败"+xhr.message)}})}

            完整代码

    <script type="text/javascript">$(document).ready(function() {//	页面一加载就调用方法showAddressList();})function showAddressList() {// 展示之前将收货地址列表清空$("#address-list").empty();$.ajax({url: "/addresses",type: "GET",dataType: "json",success: function (json) {if (json.state == 200) {// 获取省列表,包括所哟省名称let list = json.data;// 遍历省列表for (let i = 0; i < list.length; i++) {// #{tag} 占位符let tr = '<tr>\n' +'<td>#{tag}</td>\n' +'<td>#{name}</td>\n' +'<td>#{address}</td>\n' +'<td>#{phone}</td>\n' +'<td><a class="btn btn-xs btn-info"><span class="fa fa-edit"></span> 修改</a></td>\n' +'<td><a class="btn btn-xs add-del btn-info"><span class="fa fa-trash-o"></span> 删除</a></td>\n' +'<td><a onclick="setDefault(#{aid})" class="btn btn-xs add-def btn-default">设为默认</a></td>\n' +'</tr>'//	将列表的tr清空,替代成新的tr//	replace() 替换tr = tr.replace("#{tag}", list[i].tag)tr = tr.replace("#{name}", list[i].name)tr = tr.replace("#{address}", list[i].address)tr = tr.replace("#{phone}", list[i].phone)// 获取aidtr = tr.replace("#{aid}", list[i].aid)//	替换完成之后,将tr追加到address-list列表中$("#address-list").append(tr)}//	按照降序排列的话,第一项是设置的默认项,那么”设为默认地址“这个按钮应该隐藏//	将某个元素隐藏使用hide()方法$(".add-def:eq(0)").hide();}else{alert("用户收货地址列表加载失败")}}})}function setDefault(aid) {$.ajax({url: "/addresses/setDefault/"+ aid,type: "POST",dataType: "json",success: function (json) {if (json.state == 200) {alert("设置默认地址成功")//	将列表的tr清空,替代成新的tr//	重新调用获取列表的方法showAddressList();}else{alert("设置默认地址失败")}},error: function (xhr) {alert("设置默认地址失败"+xhr.message)}})}</script>

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
    如若转载,请注明出处:http://www.pswp.cn/bicheng/85419.shtml
    繁体地址,请注明出处:http://hk.pswp.cn/bicheng/85419.shtml

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

    相关文章

    LabVIEW FPGA 资源扩展

    针对NI CompactRIO 9045 控制器 Kintex-7 70T FPGA 资源不足问题&#xff0c;通过 NI 9151 R 系列可重配置 I/O 模块扩展外部 FPGA 处理能力&#xff0c;在保留原有机箱架构下实现实时任务分流&#xff0c;解决Slice、LUT 等资源紧张问题&#xff0c;提升系统并行处理能力。 ​…

    【漏洞复现】Apache Kafka Connect 任意文件读取漏洞(CVE-2025-27817)

    文章目录 前言一、Apache Kafka 简介二、漏洞描述三、影响版本四、FOFA查询语句五、漏洞原理分析六、漏洞复现七、修复建议前言 由于Apache Kafka客户端未对用户输入进行严格验证和限制,未经身份验证的攻击者可通过构造恶意配置读取环境变量或磁盘任意内容,或向非预期位置发…

    day13-软件包管理

    1.每日复盘与今日内容 1.1复盘 yum源/apt源配置文件,核心下载地址.二进制部署服务.编译安装软件. 2.软件包管理-实战部分 2.1 yum源/apt源配置 源下载软件的地址配置多种源 1️⃣系统也有默认的源&#xff0c;里面也包含很多常用的软件. 2️⃣安装nginx、yum源 3️⃣安…

    榕壹云快递寄件系统:聚合快递、智能追踪、二次开发,一站式物流解决方案

    在电商物流高速发展的今天&#xff0c;快递寄件需求呈现爆炸式增长。传统分散的寄件方式效率低下&#xff0c;用户迫切需要一个整合多家快递公司的便捷平台。榕壹云公司开发的快递寄件系统应运而生&#xff0c;通过聚合多家快递资源、优化操作流程、提供丰富的功能模块&#xf…

    一款功能强大的专业CSV编辑工具

    Rons Data Edit是一款为Windows操作系统设计的现代CSV文件编辑器&#xff0c;它结合了优雅、强大和易用性&#xff0c;它可以打开任何格式的分隔文本文件(如CSV、TSV等)&#xff0c;并允许用户完全控制文件的内容和结构。 功能特点 支持明暗主题&#xff0c;可以在预定义的20多…

    什么是软件架构?和系统设计有何区别?

    一、软件架构的定义与核心要素 1.1 基本概念 软件架构(Software Architecture)是指系统的高层结构,包含: 组件(Components)及其相互关系指导设计的架构原则和决策满足质量属性(Quality Attributes)的技术方案引用权威定义:IEEE 1471标准将架构描述为"系统的基本组织,…

    九尾狐编程语言新算法“超维时空演算体”

    一、核心架构设计 1&#xff0e;量子&#xfe63;生物混合计算基座 ◇底层采用量子纠缠拓扑网络&#xff0c;处理超越经 典计算复杂度的问题&#xff08;如 NP - Hard 优化&#xff09;&#xff0e;中层嵌入类脑脉冲神经网络&#xff0c;模拟人脑跨领域联想能力&#xff0c;…

    RoboVerse--为机器人学习打造的大一统世界--UC Berkeley...--2025.4.26

    ROBOVERSE 包含一个可扩展的仿真平台、大规模的合成数据集&#xff0c;以及统一的基准测试。 该仿真平台通过统一协议&#xff0c;支持新任务和演示的无缝接入&#xff0c;保证了灵活性和可扩展性。该数据集包含 1,000 多个多样化任务及超过 1,000 万个状态转换&#xff0c;构…

    Fiddler抓包工具实战指南:结合Charles、Postman优化Web与移动调试流程

    在Web开发与移动端调试的工作流程中&#xff0c;网络请求的可视化、分析和控制能力对开发效率有着决定性影响。特别是在处理复杂接口联调、性能瓶颈排查&#xff0c;甚至安全漏洞分析时&#xff0c;一款可靠的抓包工具几乎成为了每一位开发者的“标配”。 Fiddler作为长期深受…

    6/19作业

    思维导图 单选题 树 1. 向一棵平衡二叉树中插入一个结点后&#xff0c;一定会改变其平衡性。 &#xff08; &#xff09; A 正确 B 错误 正确答案&#xff1a;B 你的答案&#xff1a;A 官方解析&#xff1a; 向平衡二叉树中插入节点并不一定会改变其平衡性。平衡二叉树(如AVL树…

    angular 图斑点击,列表选中并滚动到中间位置

    如图所示&#xff1a; html代码&#xff1a; 1. #listContainer 2. [attr.data-id]"center.id" <div class"resTableCss" #listContainer><div *ngFor"let center of tbList" [attr.data-id]"center.id" class"res-it…

    Java线程同步的简单理解

    为什么需要线程同步 对于以下代码&#xff1a;两个线程对同一个变量分别进行100000次加一和减一操作&#xff0c;但是每次运行的输出基本都是不同的&#xff08;注意线程的join操作保证了两个线程都运行完之后才执行System.out.println&#xff09; import org.junit.Test;pu…

    Makefile的通用模板 + 倒计时小程序(13)

    文章目录 Makefile 的通用模板1. Makefile 的推导原则2. 设计 Makefile 的通用模板3. 通用模板代码&#xff08;可以直接拿来用&#xff09; Linux 第一个系统程序-进度条&#xff08;7-3.00.00&#xff09;1. 补充回车与换行2. 行缓冲区3. 倒计时小程序 Makefile 的通用模板 …

    【ArcGIS】水文分析与流域划分

    【ArcGIS】水文分析与流域划分 一、基础数据处理1、下载数据2、拼接DEM数据3、填充洼地4、流向分析5、流量分析6、河网生成&#xff08;栅格计算器&#xff09;7、河网分级8、河流链接&#xff08;提取子流域的关键&#xff09; 二、多个小流域提取1、捕捉倾泻点2、集水区&…

    【C++】简单工厂模式/工厂方法模式/抽象工厂模式对比

    目录 一、简单工厂模式&#xff08;Simple Factory Pattern&#xff09;二、工厂方法模式&#xff08;Factory Method Pattern&#xff09;三、抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;四、三者对比总结五、选择建议如果这篇文章对你有所帮助&#xff0c…

    博图SCL中CONTINUE语句详解:高效循环控制案例

    博图SCL中CONTINUE语句详解&#xff1a;高效循环控制利器 在博图&#xff08;TIA Portal&#xff09;的SCL&#xff08;结构化控制语言&#xff09;编程中&#xff0c;CONTINUE语句是优化循环流程的强大工具。它允许您**跳过当前循环迭代的剩余代码&#xff0c;直接进入下一次…

    django HttpResponse 加返回码

    在Django框架中&#xff0c;HttpResponse对象是用来构造HTTP响应并将其发送回客户端的。当你创建一个HttpResponse对象时&#xff0c;你可以指定一个返回码&#xff08;或状态码&#xff09;&#xff0c;这是HTTP响应的一部分&#xff0c;用来表示请求的处理结果。状态码是三位…

    【俄语图片文字识别】批量识别俄语图片文字,识别俄语图片文字的操作步骤和注意事项

    场景&#xff1a;在俄语学习&#xff0c;俄语工作中经常遇到一些文字图片&#xff0c;如何将韩语图片文字从图片上扣下来&#xff0c;我们可以直接复制粘贴&#xff0c;提高我们的工作效率 我们会用到一款小工具&#xff1a; 软件操作步骤&#xff1a; 第一步、打开软件 第二…

    关于AB PLC的ethernet/IP 通信 c++搭建

    1.下载开源的libplctag库 2.通过Cmake-gui生成工程文件 3.编译生成对应的Debug 4.配置VS studio 源码 #include "libplctag.h" #include <cstring> #include <iostream> #include <thread> int main() { plc_tag_set_debug_level(PLCTAG_DEB…

    实验分享|自研局部DIC-GPU算法与开源GPU算法对比实验

    1实验背景 数字图像相关法DIC是材料力学领域研究的关键技术&#xff0c;其中局部DIC凭借亚像素级精度、全场测量等优势&#xff0c;成为材料局部变形分析的优选方案。传统CPU计算难以应对局部DIC数万个子区并行计算需求&#xff0c;新兴GPU算法一定程度提高了计算效率&#xf…