【云岚到家】-day02-3-我的地址簿


1 用户端定位

2.1 需求分析

本项目在用户端和服务端都有定位的需求,本节分析用户端即小程序端的定位需求。

2.1.1 用户端首页定位

用户端在小程序认证通过后会自动进行定位,也可以在首页手动定位,定位成功后用户在查询家政服务项目时会根据定位的城市查询该城市有哪些服务项目。

手动定位过程如下图:

在这里插入图片描述

在这里插入图片描述

2.1.2 高德地图配置

小程序端的定位是通过手机的定位模块进行定位,定位成功获取经纬度坐标,平台根据经纬度坐标请求地图服务获取经纬度坐标对应的具体位置。

小程序首先通过微信提供的方法拿到经纬度坐标,然后请求后端获取具体的位置,后端会请求高德地图根据经纬度获取具体的城市信息。

要测试用户端定位的流程首先需要在高德地图开通地图定位服务。

参考“高德地图web服务配置文档” 获取访问接口的key。

进入nacos配置jzo2o-publics.yml中高德地图key。

在这里插入图片描述

2.1.3 测试定位

启动成功,点击“快速登录”,先同意服务条款,再允许获取位置信息,点击“允许”观察Network,请求定位接口/publics/map/regeo?location=,如下图:
在这里插入图片描述

到此说明定位测试通过。

下边介绍一种虚拟定位的设置,这个在开发中经常使用,虚拟定位即不是按手机位置进行定位,比如:你在北京,想测试定位到郑州某个位置该如何操作呢?

在微信开发环境可以指定小程序虚拟定位。

进入https://lbs.amap.com/tools/picker,选择一个北京的地方

请添加图片描述

116.394,39.905

首先打开虚拟定位,指定经纬度,如下图:

在这里插入图片描述

重新定位发起请求

在这里插入图片描述

code: 200
data: {cityCode: "010", province: "北京市", city: null, district: "西城区",}
city: null
cityCode: "010"
district: "西城区"
fullAddress: "北京市西城区西长安街街道人民大会堂全国人大常委会"
province: "北京市"
msg: "OK"

2.2 阅读代码

2.2.1 用户端定位交互流程

在这里插入图片描述

2.2.2 阅读代码

定位过程中小程序请求publics服务的接口查询经纬度对应的位置信息,调用/publics/map/regeo接口,下边阅读/publics/map/regeo接口。

在com.jzo2o.publics.controller.outer.MapController中

@GetMapping("/regeo")
@ApiOperation("根据经纬度查询地址信息")
@ApiImplicitParams({
        @ApiImplicitParam(name = "location", value = "经纬度", required = true, dataTypeClass = String.class)
})
public MapLocationResDTO getCityCodeByLocation(@NotNull(message = "坐标不能为空") @RequestParam("location") String location) {
    MapLocationDTO mapLocationDTO = mapService.getCityCodeByLocation(location);
    return BeanUtil.toBean(mapLocationDTO, MapLocationResDTO.class);
}

接口文档:

http://localhost:11503/publics/doc.html#/default/%E5%9C%B0%E5%9B%BE%E6%9C%8D%E5%8A%A1%E7%9B%B8%E5%85%B3%E6%8E%A5%E5%8F%A3/getCityCodeByLocationUsingGET

在这里插入图片描述

通过mapService的getCityCodeByLocation方法调用高德地图的查询地理编码接口

public MapLocationDTO getCityCodeByLocation(String location) {
    Map<String, Object> params = new HashMap();
    params.put("location", location);
    params.put("key", this.amapProperties.getKey());
    String jsonStr = HttpRequest.get("https://restapi.amap.com/v3/geocode/regeo?").form(params).execute().body();
    JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
    String cityCode = (String)jsonObject.getJSONObject("regeocode").getJSONObject("addressComponent").get("citycode");
    Object province = jsonObject.getJSONObject("regeocode").getJSONObject("addressComponent").get("province");
    Object city = jsonObject.getJSONObject("regeocode").getJSONObject("addressComponent").get("city");
    Object district = jsonObject.getJSONObject("regeocode").getJSONObject("addressComponent").get("district");
    Object fullAddress = jsonObject.getJSONObject("regeocode").get("formatted_address");
    return MapLocationDTO.builder().province(ObjectUtil.isEmpty(province) ? null : province.toString()).city(ObjectUtil.isEmpty(city) ? null : city.toString()).district(ObjectUtil.isEmpty(district) ? null : district.toString()).fullAddress(ObjectUtil.isEmpty(fullAddress) ? null : fullAddress.toString()).cityCode(cityCode).build();
}

高德地图的查询地理编码接口定位如下图:

在这里插入图片描述

接口文档地址:https://lbs.amap.com/api/webservice/guide/api/georegeo,大家可自行阅读。

最终接口返回省、市、县、详细位置等信息,如下:

在这里插入图片描述

为什么要调用高德地图的查询地理编码接口呢?

在foundations数据库的region区域表中有一列是city_code,高德地图返回的详细信息中city_code与region区域表中city_code是一致的,如下图:

在这里插入图片描述

小程序拿到的是经纬度坐标,通过调用此接口就可以根据经纬度得到city_code从而关联到平台具体的区域。

region表的city_code从哪来?

先从从高德地图下载拿到全国的区域信息,包括了city_code(https://lbs.amap.com/api/webservice/download)

将下载得到AMap_adcode_citycode.xlsx文件处理为json文件由前端进行保存。

前端在添加区域时从该json文件中选择区域,如下图:

在这里插入图片描述

区域信息中包括了从高德地图拿到的city_code,添加一个区域将city_code保存到了region表中。

2 我的地址簿-实战

注意:我的地址簿在用户下单时需要使用,优先完成。

2.1 需求分析

2.1.1 新增地址簿

用户下单时需要选择服务地址(相当于收货地址),在“我的”–》“我的地址”界面维护地址簿信息。

在这里插入图片描述

点击“我的地址”进入地址簿管理界面

在这里插入图片描述

点击“新增地址”:

在这里插入图片描述

点击“定位”打开定位窗口

在这里插入图片描述

默认通过手机定位模块定位到当前所在位置,也可以输入地址进行搜索,点击具体的地址,确认无误点击“确定”完成定位。

完成定位后在城市和详细地址栏中自动填入定位的地址,如下图:

在这里插入图片描述

注意:前端提交的经纬度是一个字符串,格式为:“经度,纬度”,前端请求publics服务进行定位,在调试时需要启动publics服务。

填写联系人和电话,点击“确定”

在这里插入图片描述

点击“确定”将地址簿信息保存成功。

注意:默认地址一个人只有一个,如果设置新地址为默认地址需要取消旧的默认地址。

2.1.2 地址簿查询

地址簿新增成功在我的地址中查询,如下图:

在这里插入图片描述

2.1.3 地址簿编辑

进入我的地址页面,点击“编辑”对地址簿进行修改

在这里插入图片描述
在这里插入图片描述

2.1.4 地址簿删除

进入我的地址页面,点击“删除”对地址簿进行删除

在这里插入图片描述

2.1.5 批量删除

点击“管理”对地址簿批量删除

在这里插入图片描述
在这里插入图片描述

2.2 数据表设计

到jzo2o-customer数据库的address_book表中。

CREATE TABLE `address_book` (
  `id` bigint NOT NULL COMMENT '主键',
  `user_id` bigint NOT NULL COMMENT '用户id',
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '名称',
  `phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '电话',
  `province` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '省份',
  `city` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '市级',
  `county` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '区/县',
  `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '详细地址',
  `lon` double(10,5) DEFAULT NULL COMMENT '经度',
  `lat` double(10,5) DEFAULT NULL COMMENT '纬度',
  `is_default` int NOT NULL DEFAULT '0' COMMENT '是否为默认地址,0:否,1:是',
  `is_deleted` int NOT NULL DEFAULT '0' COMMENT '是否已删除,0:未删除,1:已删除',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `create_by` bigint DEFAULT NULL COMMENT '创建者',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `update_by` bigint DEFAULT NULL COMMENT '更新者',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='地址薄'

2.3 接口设计

2.3.1 新增地址簿

2.3.1.1 新增地址簿接口

接口名称:新增地址簿

接口路径:POST/customer/consumer/address-book

请求数据类型 application/json

在这里插入图片描述

在这里插入图片描述

2.3.1.2 controller

创建com.jzo2o.customer.controller.consumer.AddressBookController

@RestController("addressBookController")
@RequestMapping("/consumer/address-book")
@Api(tags = "用户端 - 地址薄相关接口")
public class AddressBookController {
    @Resource
    private IAddressBookService addressBookService;
    /**
     * 新增地址薄
     * @param addressBookUpsertReqDTO
     */
    @PostMapping
    @ApiOperation("新增地址薄")
    public void add(@RequestBody AddressBookUpsertReqDTO addressBookUpsertReqDTO) {
        addressBookService.add(addressBookUpsertReqDTO);
    }
}
2.3.1.3 service

接口:

void add(AddressBookUpsertReqDTO addressBookUpsertReqDTO);

实现

过程:1、先从threadlocal中获取当前用户id。2、查询是否有默认地址。3、最后组装数据,完成插入

@Override
@Transactional
public void add(AddressBookUpsertReqDTO addressBookUpsertReqDTO) {
    AddressBook addressBook= BeanUtil.toBean(addressBookUpsertReqDTO, AddressBook.class);
    //1.获取当前用户id
    Long userId = UserContext.currentUserId();
    addressBook.setUserId(userId);
    //2.默认地址处理
    if(addressBook.getIsDefault().equals(1)) {
        //2.1.查询当前用户的默认地址
        AddressBook defaultAddress = lambdaQuery()
                .eq(AddressBook::getUserId, userId)
                .eq(AddressBook::getIsDefault, "1")
                .one();
        //2.2.如果有默认地址,将其改为非默认
        if(defaultAddress != null) {
            defaultAddress.setIsDefault(0);
            updateById(defaultAddress);
        }
    }
    //3.新增地址
    save(addressBook);
}
2.3.1.4 测试

因为还没写page,所以前端暂时没法看,查看数据库

在这里插入图片描述

已经成功插入

2.3.1.5 高德地图地理编码

发现个小问题,忘了插入经纬度了。那就用高德正向地址编码一下获取经纬度。

@Resource
private MapApi mapApi;
@Override
public void add(AddressBookUpsertReqDTO addressBookUpsertReqDTO) {
    //0.设置经纬度
    LocationResDTO locationByAddress = mapApi.getLocationByAddress(addressBookUpsertReqDTO.getAddress());
    String location=locationByAddress.getLocation();
    Double lon= Double.valueOf(location.split(",")[0]);
    Double lat= Double.valueOf(location.split(",")[1]);
    AddressBook addressBook= BeanUtil.toBean(addressBookUpsertReqDTO, AddressBook.class);
    addressBook.setLon(lon);
    addressBook.setLat(lat);
    //1.获取当前用户id
    Long userId = UserContext.currentUserId();
    addressBook.setUserId(userId);

在这里插入图片描述

2.3.2 地址簿查询

2.3.2.1 地址薄分页查询接口

接口名称:地址薄分页查询

接口路径:GET/customer/consumer/address-book/page

请求数据类型 application/x-www-form-urlencoded

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.3.2.2 响应实体类-AddressResDto

创建com.jzo2o.customer.model.dto.response.AddressResDto

@Data
@ApiModel("地址响应体")
public class AddressResDto {
    /**
     * 详细地址
     */
    @ApiModelProperty("详细地址")
    private String address;

    /**
     * 市
     */
    @ApiModelProperty("市")
    private String city;

    /**
     * 区
     */
    @ApiModelProperty("区")
    private String county;

    /**
     * 经度
     */
    @ApiModelProperty("经度")
    private Double lon;

    /**
     * 纬度
     */
    @ApiModelProperty("纬度")
    private Double lat;

    /**
     * 更新时间
     */
    @ApiModelProperty("更新时间")
    private String updateTime;

    /**
     * 用户id
     */
    @ApiModelProperty("用户id")
    private Long userId;

    /**
     * 是否为默认地址
     */
    @ApiModelProperty("是否为默认地址")
    private Integer isDefault;

    /**
     * 省份
     */
    @ApiModelProperty("省份")
    private String province;

    /**
     * 创建时间
     */
    @ApiModelProperty("创建时间")
    private String createTime;

    /**
     * 手机号
     */
    @ApiModelProperty("手机号")
    private String phone;

    /**
     * 名称
     */
    @ApiModelProperty("名称")
    private String name;

    /**
     * 地址id
     */
    @ApiModelProperty("地址id")
    private Long id;
}
2.3.2.3 controller
@GetMapping("/page")
@ApiOperation("分页查询地址薄")
public PageResult<AddressResDto> page(AddressBookPageQueryReqDTO addressBookPageQueryReqDTO) {
    return addressBookService.pageAddress(addressBookPageQueryReqDTO);
}
2.3.2.4 service

接口

PageResult<AddressResDto> pageAddress(AddressBookPageQueryReqDTO addressBookPageQueryReqDTO);

实现

@Override
public PageResult<AddressResDto> pageAddress(AddressBookPageQueryReqDTO addressBookPageQueryReqDTO) {
    return PageHelperUtils.selectPage(addressBookPageQueryReqDTO,
            () -> baseMapper.queryAddressListByUserId(UserContext.currentUserId()));
}
2.3.2.5 mapper

接口

List<AddressResDto> queryAddressListByUserId(@Param("userId") Long userId);

xml

<select id="queryAddressListByUserId" resultType="com.jzo2o.customer.model.dto.response.AddressResDto"
        parameterType="java.lang.Long">
    SELECT * FROM address_book WHERE user_id=#{userId} AND is_deleted=0
</select>
2.3.1.5 测试

在这里插入图片描述

2.3.3 地址薄编辑

2.3.3.1 地址薄详情接口

接口名称:地址薄详情

接口功能:修改地址簿前调用此接口先查询在页面显示

接口路径:GET/customer/consumer/address-book/{id}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.3.3.2 controller
@GetMapping("/{id}")
@ApiOperation("根据id查询地址薄")
public AddressBook getById(@PathVariable("id") Long id) {
    return addressBookService.getById(id);
}
2.3.3.3 地址薄修改接口

接口名称:地址薄修改

接口功能:地址薄修改提交

接口路径:PUT/customer/consumer/address-book/{id}

请求数据类型 application/json

在这里插入图片描述
在这里插入图片描述

2.3.3.4 controller
@PutMapping("/{id}")
@ApiOperation("修改地址薄")
public AddressBook update(@PathVariable("id") Long id, @RequestBody AddressBookUpsertReqDTO addressBookUpsertReqDTO) {
    return addressBookService.update(id, addressBookUpsertReqDTO);
}
2.3.3.5 service

接口

AddressBook update(Long id, AddressBookUpsertReqDTO addressBookUpsertReqDTO);

实现

@Override
@Transactional
public AddressBook update(Long id, AddressBookUpsertReqDTO addressBookUpsertReqDTO) {
    //1.设置经纬度
    LocationResDTO locationByAddress = mapApi.getLocationByAddress(addressBookUpsertReqDTO.getAddress());
    String location=locationByAddress.getLocation();
    Double lon= Double.valueOf(location.split(",")[0]);
    Double lat= Double.valueOf(location.split(",")[1]);
    AddressBook addressBook= BeanUtil.toBean(addressBookUpsertReqDTO, AddressBook.class);
    addressBook.setLon(lon);
    addressBook.setLat(lat);
    //2.判断是否修改默认地址
    if(addressBook.getIsDefault().equals(1)) {
        //2.1.查询当前用户的默认地址
        AddressBook defaultAddress = lambdaQuery()
                .eq(AddressBook::getUserId, UserContext.currentUserId())
                .eq(AddressBook::getIsDefault, "1")
                .ne(AddressBook::getId, id)
                .one();
        //2.2.如果有默认地址,将其改为非默认
        if(defaultAddress != null) {
            defaultAddress.setIsDefault(0);
            updateById(defaultAddress);
        }
    }
    //3.更新地址
    addressBook.setId(id);
    updateById(addressBook);
    return addressBook;
}
2.3.3.6 测试

把手机号修改成17777777777

修改定位到故宫

在这里插入图片描述

在这里插入图片描述

2.3.3.7 设置默认地址

请求路径:/customer/consumer/address-book/default?id=xxx&flag=xxx

2.3.3.8 controller
@PutMapping("/default")
@ApiOperation("设置默认地址")
public AddressBook setDefault(@RequestParam("id") Long id, @RequestParam("flag") Integer flag){
    return addressBookService.setDefault(id, flag);
}
2.3.3.9 service

接口

AddressBook setDefault(Long id, Integer flag);

实现

@Override
@Transactional
public AddressBook setDefault(Long id, Integer flag) {
    //1.查询当前用户的默认地址
    AddressBook defaultAddress = lambdaQuery()
            .eq(AddressBook::getUserId, UserContext.currentUserId())
            .eq(AddressBook::getIsDefault, "1")
            .ne(AddressBook::getId, id)
            .one();
    //2.如果有默认地址,将其改为非默认
    if(defaultAddress != null) {
        defaultAddress.setIsDefault(0);
        updateById(defaultAddress);
    }
    //3.将当前地址改为默认
    AddressBook addressBook = getById(id);
    addressBook.setIsDefault(flag);
    updateById(addressBook);
    return addressBook;
}

2.3.4 地址簿删除

进入我的地址页面,点击“删除”对地址簿进行删除

在这里插入图片描述

为了删除方便,创建了四个地址,码农烧烤、探花、骑车、宝哥

在这里插入图片描述

2.3.4.1 地址簿批量删除接口

接口名称:地址簿批量删除

接口路径:DELETE/customer/consumer/address-book/batch

在这里插入图片描述

在这里插入图片描述

2.3.4.2 controller
@DeleteMapping("/batch")
@ApiOperation("批量删除地址薄")
public void deleteBatch(@RequestBody List<Long> ids) {
    addressBookService.removeByIds(ids);
}
2.3.4.3 测试

删除探花和骑车

在这里插入图片描述

查看数据库,已经将is_deleted字段置为1

2.3.4.4 逻辑删除

查看控制台

在这里插入图片描述

发现deleteBatchIds执行的Update逻辑删除,这是哪里配置的呢?

查看mysql的nacos配置,发现配置了logic-delete-field字段,指向isDeleted,实现逻辑删除,也可以在实体类的属性上加上 @TableLogic(value="0",delval="1") 字段实现逻辑删除

在这里插入图片描述

2.3.5 获取默认地址接口

接口名称:获取默认地址

接口功能:在下单界面先获取当前用户的默认地址,如果有默认地址则直接显示在页面中

接口路径:GET/customer/consumer/address-book/defaultAddress

请求数据类型 application/x-www-form-urlencoded

请求参数:无

在这里插入图片描述

在这里插入图片描述

2.3.5.1 controller
@GetMapping("/defaultAddress")
@ApiOperation("获取默认地址")
public AddressBookResDTO getDefaultAddress(){
    return addressBookService.getDefaultAddress();
}
2.3.5.2 service

接口

AddressBookResDTO getDefaultAddress();

实现

@Override
public AddressBookResDTO getDefaultAddress() {
    AddressBook addressBook = lambdaQuery()
            .eq(AddressBook::getUserId, UserContext.currentUserId())
            .eq(AddressBook::getIsDefault, "1")
            .one();
    if(addressBook == null) {
        return null;
    }
    return BeanUtil.toBean(addressBook, AddressBookResDTO.class);
}
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AAA码农宝哥.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值