SSM架构商城项目(九)

6.3. 收货地址-设置默认收货地址

6.3.3. 收货地址-设置默认收货地址-控制器层

设计处理设置默认收货地址的请求:

请求路径:/address/set_default.do
请求类型:GET
请求参数:uid(HttpSession), id
响应方式:ResponseResult<Void>
是否拦截:是,登录拦截,但无须修改配置

则,在AddressController中添加处理请求的方法:

@RequestMapping("/set_default")
@ResponseBody
public ResponseResult<Void> setDefault(
    HttpSession session,
    @RequestParam("id") Integer id) {
    // 从session中获取uid
    // 调用业务层对象的setDefaultAddress(uid, id)方法
    // 创建返回值对象并返回
}

由于此次操作在业务层抛出的异常都是UpdateDataException,此前在BaseController中都已经处理过,则无须重复处理!

6.3.4. 收货地址-设置默认收货地址-前端页面

关于address.html中的核心改动在于:

var html = '<div class="aim_content_one aim_active">'
    + '<span class="dzmc dzmc_active">#{tag}</span>'
    + '<span class="dzxm dzxm_normal">#{name}</span>'
    + '<span class="dzxq dzxq_normal">#{address}</span>'
    + '<span class="lxdh lxdh_normal">#{phone}</span>'
    + '<span class="operation operation_normal">'
    + ' <span class="aco_change">修改</span>|<span class="aco_delete">删除</span>'
     + '</span>'
    + '<span class="swmr swmr_normal">'
    + '<a href="javascript:setDefault(#{id});">#{default}</a>'
    + '</span>'
    + '</div>';

html = html.replace("#{id}", addresses[i].id);

function setDefault(id) {
    // 发AJAX请求,并处理结果
    var url = "../address/set_default.do";
    var data = "id=" + id;
    $.ajax({
        "url": url,
        "data": data,
        "type": "GET",
        "dataType": "json",
        "success": function(json) {
            if (json.state == 200) {
                showList();
            } else {
                alert(json.message);
            }
        },
        "error": function(xhr, textStatus, errorThrown) {
            console.log("状态码:" + xhr.readyState);
            console.log("响应码:" + xhr.status);
            console.log("响应文本:" + xhr.responseText);
            console.log("textStatus=" + textStatus);
            console.log("errorThrown=" + errorThrown);
            alert("您的登录信息已经过期,请重新登录!");
            location.href = "../web/login.html";
        }
    });
}

6.4. 收货地址-删除

6.4.1 收货地址-删除-持久层

在持久层中,应该添加执行删除的功能,在该功能的设计上,可以通过id=?作为删除条件,也可以使用id=? AND uid=?作为删除条件:

使用 id=? 作为删除条件

优点:不局限于是谁操作某条数据,可以在业务中自由组织

缺点:必须在业务层判断id的有效性,是否是当前登录的用户的数据

使用 id=? AND uid=? 作为删除条件

优点:可以确保当前登录的用户操作的必然是他自己的数据

缺点:所有用户都只能删除自己的数据,包括管理员

小结

为了保证组织业务的自由,保证项目的可扩展性,推荐使用前者,所以,持久层只使用id=?作为删除条件,最终会在业务层判断尝试删除的数据是不是当前登录的用户的数据,所以,还需要在持久层添加查询功能,根据尝试删除的数据id查出收货地址数据,后续根据登录的uid进行对比,所以,在持久层接口和映射中配置:

抽象方法

Integer delete(Integer id);

SQL语句

DELETE FROM t_address WHERE id=?

抽象方法

Address getAddressById(Integer id);

SQL语句

SELECT 
    id, uid, 
    recv_name AS recvName,
    recv_district AS recvDistrict, 
    recv_address AS recvAddress,
    recv_phone AS recvPhone, 
    recv_tel AS recvTel,
    recv_zip AS recvZip, 
    recv_tag AS recvTag, 
    is_default AS isDefault
FROM
    t_address 
WHERE 
    id=#{id}

6.4.1 收货地址-删除-业务层

创建com.company.store.service.ex.AddressNotFoundExceptionArgumentException这2个异常。

在业务层接口中添加抽象方法:

void deleteById(Integer uid, Integer id);

Address getAddressById(Integer id);

在实现类中:

public void deleteById(Integer uid, Integer id) {
    // ** 组织业务,最终删除数据 **
    // 判断数据是不是当前用户的,则根据参数id查询数据
    // 判断是否查询到数据
    // 是:数据存在,则判断参数uid和查询结果中封装的uid是否相同
    // -- 是:删除的是自己的数据,执行删除
    // -- 否:尝试删除的不是自己的数据:ArgumentException
    // 否:数据不存在,AddressNotFoundException
}

private Integer delete(Integer id) {
    Integer rows = addressMapper.delete(id);
    if (rows != 1) {
        throw new AddressNotFoundException();
    }
}

在删除业务中,还需要考虑被删除的数据是否是默认收货地址,如果是,则还需要将另一条收货地址设置为默认!此项操作涉及2个功能:

  1. 判断删除的数据是否是默认收货地址:由于在现有的逻辑中,已经是先获取要删除的数据本身,然后执行的删除,所以,直接从获取的数据中判断isDefault属性即可,则无须添加新的持久层、业务层功能;

  2. 将某条数据设置为默认收货地址:首先,设置规则为将最后添加的那条收货地址设置为默认,则需要获取最后一条添加的收货地址,则需要持久层开发新的功能:

抽象方法

Address getLatestAddress(Integer uid)

SQL语句

SELECT id FROM t_address WHERE uid=? ORDER BY id DESC LIMIT 0,1

然后,将原有逻辑调整为:

@Transactional
// ** 组织业务,最终删除数据 **
// 判断数据是不是当前用户的,则根据参数id查询数据
// 判断是否查询到数据
// 是:数据存在,则判断参数uid和查询结果中封装的uid是否相同
// -- 是:删除的是自己的数据,执行删除
// -- 判断删除的数据的isDefault是否为1
// -- -- 是:删除了默认收货地址,则查询最后添加的收货地址
// -- -- 判断是否查询到结果
// -- -- -- 是:获取数据id,调用setDefault(uid, id)
// -- -- -- 否:刚才删除的已经最后一条,则直接结束
// -- -- 否:结束
// -- 否:尝试删除的不是自己的数据:ArgumentException
// 否:数据不存在,AddressNotFoundException

由于调用了setDefault()方法,还可能抛出UpdateDataException,也应该在方法的声明中添加该异常!

6.4.3 收货地址-删除-控制器层

设计处理删除收货地址的请求:

请求路径:/address/delete.do
请求类型:GET
请求参数:uid(HttpSession), id
响应方式:ResponseResult<Void>
是否拦截:是,登录拦截,但无须修改配置

则,在AddressController中添加处理请求的方法:

@RequestMapping("/delete.do")
@ResponseBody
public ResponseResult<Void> delete(
    HttpSession session,
    @RequestParam("id") Integer id) {
    // 从session中获取uid
    // 调用业务层对象的deleteById(uid, id)方法
    // 创建返回值对象并返回
}

由于此次操作在业务层抛出的异常有AddressNotFoundExceptionArgumentExceptionUpdateDataException,此前在BaseController中前2种尚未处理过,则应该添加对这2个异常的处理!

测试时,应该先登录,然后通过/address/delete.do?id=xx此类的URL进行测试。

猜你喜欢

转载自www.cnblogs.com/wood-life/p/10290881.html
今日推荐