(由于电脑故障,前一篇微信登录到高德地图的文章草稿未得到保存,需要查看到文档查看)
目录
一、服务列表
二、精选推荐
三、服务详情
四、获取默认地址
一、服务列表
由于小程序首页需要展示该区域下启用的服务分类与服务项,因此需要该接口:

接口路径:GET /foundations/customer/serve/firstPageServeList 请求参数:
响应参数(json):
{
"msg": "OK",
"code": 200,
"data": [{
"serveTypeId": 0, // 服务类型id
"serveTypeName": "", //服务类型名称
"serveTypeIcon": "", //服务类型图标
"serveTypeSortNum": 0, //服务项排序
"cityCode": "", // 城市编码
"serveResDTOList": [{
"id": 0, //区域下服务服务id
"serveItemId": 0, //服务项目id
"serveItemName": "", //服务项目名称
"serveItemIcon": "", //服务项目图标
"serveItemSortNum": 0, //服务项目排序
}]
}]
}
根据我们的业务需求,我们不需要查出哪些服务类型下没有服务项或者服务项没有绑定服务类型的服务,因此我们选择内连接,因为选择了内连接,所以谁作为主表都没有问题;然后根据响应参数对应表中字段得到三张表:
我们这里选择serve表为主表,再依次内连接完成sql语句编写:
— 查询指定区域下上架了的服务类型和项目
select
st.id as serveTypeId,
st.name as serveTypeName,
st.serve_type_icon as serveTypeIcon,
st.sort_num as serveTypeSortNum,
s.city_code as cityCode,
s.id as id,
si.id as serveItemId,
si.name as serveItemName,
si.serve_item_icon as serveItemIcon,
si.sort_num as serveItemSortNum
from serve s
inner join serve_item si on s.serve_item_id = si.id
inner join serve_type st on si.serve_type_id = st.id
where s.region_id = 1692472339767234562 and s.sale_status = 2
order by st.sort_num asc ,si.sort_num asc
这里的排序是为了选出排在前两个的服务类型以及其内前四个的服务项
接下来开始开发:
在jzo2o-foundations模块下新建com.jzo2o.foundations.controller.consumer.ServeController:
package com.jzo2o.foundations.controller.consumer;
import com.jzo2o.foundations.model.dto.response.ServeCategoryResDTO;
import com.jzo2o.foundations.service.IServeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController("consumerServeController")
@RequestMapping("/customer/serve")
@Api(tags = "用户端 – 区域相关接口")
public class ServeController {
@Resource
private IServeService serveService;
@GetMapping("/firstPageServeList")
@ApiOperation("首页服务分类及项目")
public List<ServeCategoryResDTO> firstPageServeList(Long regionId) {
return serveService.firstPageServeList(regionId);
}
}
IServeService:
/**
* 查询指定区域下上架的服务分类及项目信息
*
* @param regionId 区域id
* @return 服务分类及项目信息
*/
List<ServeCategoryResDTO> firstPageServeList(Long regionId);
ServeServiceImpl:
@Override
public List<ServeCategoryResDTO> firstPageServeList(Long regionId) {
//1 对区域进行校验
Region region = regionMapper.selectById(regionId);
if (ObjectUtil.isNull(region) || region.getActiveStatus() != 2) {
return Collections.emptyList();
}
//2. 查询指定区域下上架的服务分类及项目信息
List<ServeCategoryResDTO> list = baseMapper.findListByRegionId(regionId);
if (CollUtil.isEmpty(list)) {
return Collections.emptyList();
}
//3. 截取
list = CollUtil.sub(list, 0, Math.min(list.size(), 2));//服务类型截取
list.forEach(e ->
//服务项目截取
e.setServeResDTOList(CollUtil.sub(e.getServeResDTOList(), 0, Math.min(e.getServeResDTOList().size(), 4)))
);
return list;
}
ServeMapper:
/**
* 查询指定区域下上架的服务分类及项目信息
*
* @param regionId 区域id
* @return 服务分类及项目信息
*/
List<ServeCategoryResDTO> findListByRegionId(Long regionId);
ServeMapper.xml:
<!–自定义结果封装–>
<resultMap id="serveMap1" type="com.jzo2o.foundations.model.dto.response.ServeCategoryResDTO">
<result column="serveTypeId" property="serveTypeId"></result>
<result column="serveTypeName" property="serveTypeName"></result>
<result column="serveTypeIcon" property="serveTypeIcon"></result>
<result column="cityCode" property="cityCode"></result>
<result column="serveTypeSortNum" property="serveTypeSortNum"></result>
<collection property="serveResDTOList" ofType="com.jzo2o.foundations.model.dto.response.ServeSimpleResDTO">
<result column="id" property="id"></result>
<result column="serveItemId" property="serveItemId"></result>
<result column="serveItemName" property="serveItemName"></result>
<result column="serveItemIcon" property="serveItemIcon"></result>
<result column="serveItemSortNum" property="serveItemSortNum"></result>
</collection>
</resultMap>
<select id="findListByRegionId" resultMap="serveMap1">
select
st.id as serveTypeId,
st.name as serveTypeName,
st.serve_type_icon as serveTypeIcon,
st.sort_num as serveTypeSortNum,
s.city_code as cityCode,
s.id as id,
si.id as serveItemId,
si.name as serveItemName,
si.serve_item_icon as serveItemIcon,
si.sort_num as serveItemSortNum
from serve s
inner join serve_item si on s.serve_item_id = si.id
inner join serve_type st on si.serve_type_id = st.id
where s.region_id = #{regionId} and s.sale_status = 2
order by st.sort_num asc ,si.sort_num asc
</select>
这里介绍一下这个封装,他是将我们查到的表格结果转换成对象用的,我们查到的结果是这样的(以北京市为例):
然后我们手动将查到的表格字段一一封装给对象当中的属性,最后一个List<ServeSimpleResDTO>属性的则需要进入该泛型对象一个个封装其内部属性,最终得到的结果如下: 
效果展示:

二、精选推荐
在门户有一块区域叫精选推荐,此处展示系统设置为热门并且上架的服务项目(按服务修改时间降序排序)
请求路径:GET /foundations/customer/serve/hotServeList 请求、响应参数:
分析相关得到表结构:

— 查询指定区域下 上架 热门的服务项目信息
select
s.id as id,
s.city_code as cityCode,
si.name as serveItemName,
s.serve_item_id as serveItemId,
si.unit as unit,
si.detail_img as detailImg,
s.price as price,
si.img as serveItemImg
from serve s inner join serve_item si on s.serve_item_id = si.id
where s.region_id = 1692472339767234562
and s.is_hot = 1
and s.sale_status = 2
order by s.update_time desc
ServeController:
@GetMapping("/hotServeList")
@ApiOperation("精选推荐")
public List<ServeAggregationSimpleResDTO> hotServeList(Long regionId) {
return serveService.hotServeList(regionId);
}
IServeservice:
/**
* 查询指定区域下上架且热门的服务项目信息
*
* @param regionId 区域id
* @return 服务项目信息
*/
List<ServeAggregationSimpleResDTO> hotServeList(Long regionId);
ServeServiceImpl:
@Override
public List<ServeAggregationSimpleResDTO> hotServeList(Long regionId) {
//1 对区域进行校验
Region region = regionMapper.selectById(regionId);
if (ObjectUtil.isNull(region) || region.getActiveStatus() != 2) {
return Collections.emptyList();
}
//2 查询指定区域下上架且热门的服务项目信息
return baseMapper.findServeListByRegionId(regionId);
}
ServeMapper:
/**
* 查询指定区域下上架且热门的服务项目信息
*
* @param regionId 区域id
* @return 服务项目信息
*/
List<ServeAggregationSimpleResDTO> findServeListByRegionId(Long regionId);
ServeMapper.xml:
<select id="findServeListByRegionId"
resultType="com.jzo2o.foundations.model.dto.response.ServeAggregationSimpleResDTO"
parameterType="java.lang.Long">
select
s.id as id,
s.city_code as cityCode,
si.name as serveItemName,
s.serve_item_id as serveItemId,
si.unit as unit,
si.detail_img as detailImg,
s.price as price,
si.img as serveItemImg
from serve s inner join serve_item si on s.serve_item_id = si.id
where s.region_id = #{regionId}
and s.is_hot = 1
and s.sale_status = 2
order by s.update_time desc
</select>
效果展示:

三、服务详情
点击服务列表中的某个服务项,即可进入到服务详情页面 请求路径:GET /foundations/customer/serve/{id} 请求、响应参数:

ServeController:
@GetMapping("/{id}")
@ApiOperation("查询服务详情")
public ServeAggregationSimpleResDTO findById(@PathVariable("id") Long id) {
return serveService.findById(id);
}
IServeService:
/**
* 查询服务详情
*
* @param id 服务id
* @return 服务详情信息
*/
ServeAggregationSimpleResDTO findById(Long id);
ServeServiceImpl:
@Override
public ServeAggregationSimpleResDTO findById(Long id) {
//1. 根据服务id去serve表中查询服务信息(内含服务项目id)
Serve serve = baseMapper.selectById(id);
if (ObjectUtil.isNull(serve)){
throw new ForbiddenOperationException("服务不存在");
}
//2. 根据服务项目id去serve_item表中查询服务项目信息
ServeItem serveItem = serveItemMapper.selectById(serve.getServeItemId());
if (ObjectUtil.isNull(serveItem)){
throw new ForbiddenOperationException("服务项目不存在");
}
//3. 将两部分内容组装成返回结果
ServeAggregationSimpleResDTO dto = BeanUtil.copyProperties(serve, ServeAggregationSimpleResDTO.class);
dto.setServeItemName(serveItem.getName());
dto.setServeItemImg(serveItem.getImg());
dto.setDetailImg(serveItem.getDetailImg());
dto.setUnit(serveItem.getUnit());
return dto;
}
之前都是采用多表联合查询的方式来处理的,其实也可以采用分步查询: 多表联查:效率比较高,但是sql书写困难,产生的笛卡尔积较大 分步查询:效率比较低,但是sql书写简单,产生的笛卡尔积较小
如何消除笛卡尔积? 分布查询可以完全避免笛卡尔积,因为该方法根本没有表之间的连接,就不存在字段之间相乘导致的笛卡尔积了; SELECT * FROM table1, table2(交叉连接)会导致笛卡尔积的生成,我们加上WHERE连接字段即可消除笛卡尔积:SELECT * FROM table1, table2 WHERE table1.linkId = table2.linkId(这是由于该写法其实是隐式内连接,跟SELECT * FROM table1 INNER JOIN table2 ON table1.linkId = table2.linkId这样写没什么区别);同样地,外连接SELECT * FROM table1 LEFT JOIN table2 ON table1.linkId = table2.linkId也可以消除笛卡尔积; 接下来介绍一下为什么内外连接连接之后可以消除笛卡尔积:实际上,只要有连接就会产生笛卡尔积,数据库会将所有组合的情况列举出来,再通过我们的ON或WHERE连接字段进行筛选过滤从而消除笛卡尔积;
效果展示:

四、获取默认地址
在立即预约界面会尝试获取当前用户的默认收货地址,如果有默认地址则直接显示在页面中
接口路径:GET /customer/consumer/address-book/defaultAddress 请求参数:无 响应参数:
在jzo2o-customer模块创建com.jzo2o.customer.controller.consumer.AddressBookController:
package com.jzo2o.customer.controller.consumer;
import com.jzo2o.api.customer.dto.response.AddressBookResDTO;
import com.jzo2o.customer.service.IAddressBookService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController("consumerAddressBookController")
@RequestMapping("/consumer/address-book")
@Api(tags = "用户端 – 用户地址相关接口")
public class AddressBookController {
@Autowired
private IAddressBookService addressBookService;
@GetMapping("/defaultAddress")
@ApiOperation("查询用户默认地址值")
public AddressBookResDTO findDefaultAddress(){
return addressBookService.findDefaultAddress();
}
}
IAddressBookService:
/**
* 查询用户默认地址值
*
* @return 用户默认地址
*/
AddressBookResDTO findDefaultAddress();
AddressBookServiceImpl:
@Override
public AddressBookResDTO findDefaultAddress() {
//用户id 默认地址
//select * from address_book where user_id = 登录用户 and is_default = 1
AddressBook addressBook = this.lambdaQuery()
.eq(AddressBook::getUserId, UserContext.currentUserId())//登录用户id
.eq(AddressBook::getIsDefault, 1)//默认地址
.one();
if (ObjectUtil.isNull(addressBook)){
return null;
}
//转换
return BeanUtil.copyProperties(addressBook,AddressBookResDTO.class);
}
效果展示:

网硕互联帮助中心





评论前必须登录!
注册