【云岚到家】-day02-我的地址簿(实战)
【云岚到家】-day02-我的地址簿(实战)
1.用户端定位
1.1 需求分析
本项目在用户端和服务端都有定位的需求,本节分析用户端即小程序端的定位需求
1.1.1 用户端首页定位
用户端在小程序认证通过后会自动进行定位,也可以在首页手动定位,定位成功后用户在查询家政服务项目时会根据定位的城市查询该城市有哪些服务项目
手动定位过程如下图:
点击下图箭头位置进行手动定位
定位成功再次进入首页发现位置变为新地址,如下图:
1.1.2 高德地图配置
小程序端的定位是通过手机的定位模块进行定位,定位成功获取经纬度坐标,平台根据经纬度坐标请求地图服务获取经纬度坐标对应的具体位置
小程序首先通过微信提供的方法拿到经纬度坐标,然后请求后端获取具体的位置,后端会请求高德地图根据经纬度获取具体的城市信息
要测试用户端定位的流程首先需要在高德地图开通地图定位服务
1.1.2.1 高德地图web服务配置
获取访问接口的key
成为开发者并创建 key,登录控制台,登录 高德开放平台控制台,如果没有开发者账号,请注册开发者
进入应用管理,创建新应用
创建 key:点开新应用**,**新应用中添加 key,服务平台选择 Web 服务
获取 key:创建成功后,可获取 key
到此我们获取高德地图接口key
在nacos配置key:进入nacos配置jzo2o-publics.yml中高德地图key
1.1.3 测试定位
启动jzo2o-publics服务。启动小程序,先清除缓存再进行编译,启动成功,点击“快速登录”,先同意服务条款,再允许获取位置信息, 点击“允许”观察Network,请求定位接口/publics/map/regeo?location=
/publics/map/regeo接口返回经纬度对应的城市信息
完整内容如下:
{"code":200,
"msg":"OK",
"data":
{"cityCode":"010","province":"北京市","city":null,"district":"昌平区","fullAddress":"北京市昌平区城北街道中共北京市昌平区委员会北京市昌平区人民政府"
}
}
到此说明定位测试通过
下边介绍一种虚拟定位的设置,这个在开发中经常使用,虚拟定位即不是按手机位置进行定位,比如:你在北京,想测试定位到郑州某个位置该如何操作呢?
在微信开发环境可以指定小程序虚拟定位。
首先打开虚拟定位,指定经纬度,如下图:
经纬度坐标可以使用高德地图的坐标拾取工具获取:
注册高德地图,进入https://lbs.amap.com/tools/picker,即可输入一个具体的位置拿到经纬度,将下图中获取的经纬度设置到上图的位置,清除缓存重新编译小程序即可按虚拟定位去定位
小结
用户端定位的流程是什么?
小程序通过微信获取手机当前位置(经纬度)
小程序请求后端获取经纬度对应的城市等详细位置信息
小程序首页显示定位的城市
1.1.4 阅读代码
1.用户端定位交互流程
2).阅读代码
定位过程中小程序请求publics服务的接口查询经纬度对应的位置信息,调用/publics/map/regeo接口,下边阅读/publics/map/regeo接口
@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);
}
通过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();
}
高德地图的查询地理编码接口定位如下图:
最终接口返回省、市、县、详细位置等信息,如下:
为什么要调用高德地图的查询地理编码接口呢?
在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 `jzo2o-customer`.address_book
(
id bigint not null comment '主键' constraint `PRIMARY` primary key,
user_id bigint not null comment '用户id',
name varchar(255) not null comment '名称',
phone varchar(255) not null comment '电话',
province varchar(255) not null comment '省份',
city varchar(255) not null comment '市级',
county varchar(255) not null comment '区/县',
address varchar(255) not null comment '详细地址',
lon double(10, 5) null comment '经度',
lat double(10, 5) null comment '纬度',
is_default int default 0 not null comment '是否为默认地址,0:否,1:是',
is_deleted int default 0 not null comment '是否已删除,0:未删除,1:已删除',
create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
create_by bigint null comment '创建者',
update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
update_by bigint null comment '更新者'
)comment '地址薄' charset = utf8mb4;
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
package com.jzo2o.customer.controller.consumer;
@RestController("addressBookController")
@RequestMapping("/consumer/address-book")
@Api(tags = "用户端 - 地址薄相关接口")
public class AddressBookController {
@Autowired
private IAddressBookService addressBookService;
/**
* 新增地址薄
*/
@PutMapping("customer/consumer/address-book")
@ApiOperation(value = "新增地址薄")
public void addAddressBook(AddressBookUpsertReqDTO addressBookUpsertReqDTO) {
addressBookService.addAddressBook(addressBookUpsertReqDTO);
}
}
2.3.1.3 service
接口:
package com.jzo2o.customer.service;
public interface IAddressBookService extends IService<AddressBook> {
/**
* 新增地址簿
*/
void addAddressBook(AddressBookUpsertReqDTO addressBookUpsertReqDTO);
}
实现
过程:1、先从threadlocal中获取当前用户id。2、查询是否有默认地址。3、最后组装数据,完成插入
package com.jzo2o.customer.service.impl;
@Service
public class AddressBookServiceImpl extends ServiceImpl<AddressBookMapper, AddressBook> implements IAddressBookService {
@Resource
private MapApi mapApi;
/**
* 新增地址簿
* 1.先从threadlocal中获取当前用户id
* 2.查询是否有默认地址
* 3.最后组装数据,完成插入
*/
@Override
public void addAddressBook(AddressBookUpsertReqDTO addressBookUpsertReqDTO) {
AddressBook addressBook= BeanUtil.toBean(addressBookUpsertReqDTO, AddressBook.class);
//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.先从threadlocal中获取当前用户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.2 地址簿查询
2.3.2.1 地址薄分页查询接口
接口名称:地址薄分页查询
接口路径:GET/customer/consumer/address-book/page
请求数据类型 application/x-www-form-urlencoded
示例:
{
"msg": "OK",
"code": 200,
"data": {
"list": [
{
"address": "",
"city": "",
"county": "",
"lon": 0,
"updateTime": "",
"userId": 0,
"isDefault": 0,
"province": "",
"createTime": "",
"phone": "",
"name": "",
"id": 0,
"lat": 0
}
],
"total": 0,
"pages": 0
}
}
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 请求实体类-AddressBookPageQueryReqDTO
/**
* 地址薄分页查询请求
*/
@Data
@ApiModel("地址薄分页查询请求")
public class AddressBookPageQueryReqDTO extends PageQueryDTO {
}
2.3.2.4 controller
package com.jzo2o.customer.controller.consumer;
@RestController("addressBookController")
@RequestMapping("/consumer/address-book")
@Api(tags = "用户端 - 地址薄相关接口")
public class AddressBookController {
@Autowired
private IAddressBookService addressBookService;
/**
* 地址薄分页查询
*/
@GetMapping("/page")
@ApiOperation("地址薄分页查询")
public PageResult<AddressResDto> page(AddressBookPageQueryReqDTO addressBookPageQueryReqDTO) {
return addressBookService.pageAddress(addressBookPageQueryReqDTO);
}
}
2.3.2.5 service
接口
/**
* 地址薄分页查询
*/
PageResult<AddressResDto> pageAddress(AddressBookPageQueryReqDTO addressBookPageQueryReqDTO);
实现
@Override
public PageResult<AddressResDto> pageAddress(AddressBookPageQueryReqDTO addressBookPageQueryReqDTO) {
return PageHelperUtils.selectPage(addressBookPageQueryReqDTO,
() -> baseMapper.queryAddressListByUserId(UserContext.currentUserId()));
}
2.3.2.6 mapper
接口
public interface AddressBookMapper extends BaseMapper<AddressBook> {
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.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);
}
3.2.2.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.4 地址簿删除
2.3.4.1 地址簿批量删除接口
接口名称:地址薄修改
接口功能:地址薄修改提交
接口路径:PUT/customer/consumer/address-book/{id}
请求数据类型 application/json
2.3.4.2 controller
removeByIds是mp自带的方法
@DeleteMapping("/batch")
@ApiOperation("批量删除地址薄")
public void deleteBatch(@RequestBody List<Long> ids) {
addressBookService.removeByIds(ids);
}
2.3.4.3 逻辑删除
查看数据库,已经将is_deleted字段置为1,发现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
@PutMapping("/default")
@ApiOperation("设置默认地址")
public AddressBook setDefault(@RequestParam("id") Long id, @RequestParam("flag") Integer flag){
return addressBookService.setDefault(id, flag);
}
2.3.5.2 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;
}
原文地址:https://blog.csdn.net/weixin_69595694/article/details/145279909
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!