【云岚到家】-day02-1-区域服务后续开发及完善

【云岚到家】-day02-1-区域服务后续开发及完善

  • [1 区域服务后续开发](#1 区域服务后续开发)
    • [1.1 添加区域服务](#1.1 添加区域服务)
      • [1.1.1 接口定义](#1.1.1 接口定义)
        • [1.1.1.1 接口设计](#1.1.1.1 接口设计)
        • [1.1.1.2 接口定义-json](#1.1.1.2 接口定义-json)
      • [1.1.2 接口开发](#1.1.2 接口开发)
        • [1.1.2.1 mapper](#1.1.2.1 mapper)
        • [1.1.2.2 service](#1.1.2.2 service)
        • [1.1.2.3 controller](#1.1.2.3 controller)
      • [1.1.3 测试](#1.1.3 测试)
    • [1.2 修改价格](#1.2 修改价格)
      • [1.2.1 接口定义](#1.2.1 接口定义)
        • [1.2.1.1 接口设计](#1.2.1.1 接口设计)
        • [1.2.1.2 接口定义-form表单](#1.2.1.2 接口定义-form表单)
      • [1.2.2 接口开发](#1.2.2 接口开发)
        • [1.2.2.1 mapper](#1.2.2.1 mapper)
        • [1.2.2.2 service](#1.2.2.2 service)
        • [1.2.2.3 controller](#1.2.2.3 controller)
      • [1.2.3 测试](#1.2.3 测试)
    • [1.3 服务上架](#1.3 服务上架)
      • [1.3.1 接口定义](#1.3.1 接口定义)
        • [1.3.1.1 接口设计](#1.3.1.1 接口设计)
        • [1.3.1.2 接口定义-form表单格式](#1.3.1.2 接口定义-form表单格式)
      • [1.3.2 接口开发](#1.3.2 接口开发)
        • [1.3.2.1 mapper](#1.3.2.1 mapper)
        • [1.3.2.2 service](#1.3.2.2 service)
        • [1.3.2.3 controller](#1.3.2.3 controller)
      • [1.3.3 测试](#1.3.3 测试)
    • [1.4 删除区域服务开发](#1.4 删除区域服务开发)
      • [1.4.1 接口定义](#1.4.1 接口定义)
        • [1.4.1.1 接口设计](#1.4.1.1 接口设计)
        • [1.4.1.2 接口定义-form表单](#1.4.1.2 接口定义-form表单)
      • [1.4.2 接口开发](#1.4.2 接口开发)
        • [1.4.2.1 mapper](#1.4.2.1 mapper)
        • [1.4.2.2 service](#1.4.2.2 service)
        • [1.4.2.3 controller](#1.4.2.3 controller)
      • [1.4.3 测试](#1.4.3 测试)
    • [1.5 区域服务下架开发](#1.5 区域服务下架开发)
      • [1.5.1 mapper](#1.5.1 mapper)
      • [1.5.2 service](#1.5.2 service)
      • [1.5.3 controller](#1.5.3 controller)
      • [1.5.4 测试](#1.5.4 测试)
    • [1.6 设置热门开发](#1.6 设置热门开发)
      • [1.6.1 mapper](#1.6.1 mapper)
      • [1.6.2 service](#1.6.2 service)
      • [1.6.3 controller](#1.6.3 controller)
      • [1.6.4 测试](#1.6.4 测试)
    • [1.7 取消热门开发](#1.7 取消热门开发)
      • [1.7.1 mapper](#1.7.1 mapper)
      • [1.7.2 service](#1.7.2 service)
      • [1.7.3 controller](#1.7.3 controller)
      • [1.7.4 测试](#1.7.4 测试)
    • [1.8 启用区域功能完善](#1.8 启用区域功能完善)
      • [1.8.1 创建按区域id和状态查询的mapper](#1.8.1 创建按区域id和状态查询的mapper)
      • [1.8.2 增加校验逻辑](#1.8.2 增加校验逻辑)
    • [1.9 禁用区域功能完善](#1.9 禁用区域功能完善)
      • [1.9.1 增加校验逻辑](#1.9.1 增加校验逻辑)
    • [1.10 禁用服务项功能完善](#1.10 禁用服务项功能完善)
      • [1.10.1 创建按服务项id和状态查询的mapper](#1.10.1 创建按服务项id和状态查询的mapper)
      • [1.10.2 增加校验逻辑](#1.10.2 增加校验逻辑)

1 区域服务后续开发

1.1 添加区域服务

1.1.1 接口定义

1.1.1.1 接口设计

下边设计添加区域服务接口,重点设计:传入参数类型、参数内容、响应结果内容。

根据界面原型梳理操作流程:

首先进入某个区域的服务列表:

点击添加服务,如下图:

选择要添加到区域中的服务,点击"添加"按钮。

最终向serve表添加数据。

serve表存储了区域中开通的服务,根据字段信息思考数据来源:

字段名 含义 数据来源
id 服务id 主键,自动生成
serve_item_id 服务项id 接口传入
region_id 区域id 接口传入
city_code 城市编码 根据区域id查询region表得到
sale_status 售卖状态 默认为草稿状态,数据库设置了默认值
price 价格 默认为服务项的价格,用户可修改
is_hot 是否为热门 默认为非热门,数据库设置了默认值
hot_time_stamp 更新为热门的时间戳 默认空
create_time 创建时间 数据库设置了默认值
update_time 更新时间 数据库设置了默认值
create_by 创建人 由framework的MyBatisAutoFillInterceptor自动处理
update_by 更新人 由framework的MyBatisAutoFillInterceptor自动处理

根据上边的分析,通过接口传入服务项id、区域id、价格,支持多个服务传入,实现批量添加。

传入参数内容为数组,所以使用json格式。

传入参数内容包括:服务项id、区域id、价格。

响应结果内容可为空,前端根据状态码判断是否添加成功。

接口设计信息:

接口路径:POST/foundations/operation/serve/batch

请求数据类型 application/json

1.1.1.2 接口定义-json

controller

java 复制代码
@PutMapping("/batch")
@ApiOperation("批量添加区域服务")
public void batch(@RequestBody List<ServeUpsertReqDTO> serveUpsertReqDTOList) {
    return;
}

批量添加的请求参数用List来接收,@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);而最常用的使用请求体传参的无疑是POST请求了,所以使用@RequestBody接收数据时,一般都用POST方式进行提交。而GET请求一般是key-value格式,则不用添加@RequestBody

查看接口文档:

重启服务,查看swagger文档如下:

1.1.2 接口开发

1.1.2.1 mapper

添加接口只向serve表添加数据所以使用mybatisplus提供的单表CRUD方法即可无需自定义mapper接口。

1.1.2.2 service

定义service接口:

java 复制代码
void batchAdd(List<ServeUpsertReqDTO> serveUpsertReqDTOList);

定义service实现方法:

java 复制代码
@Resource
private ServeItemMapper serveItemMapper;
@Resource
private RegionMapper regionMapper;

/**
 * 批量添加区域服务
 * @param serveUpsertReqDTOList
 */
@Override
@Transactional
public void batchAdd(List<ServeUpsertReqDTO> serveUpsertReqDTOList) {
    for (ServeUpsertReqDTO serveUpsertReqDTO : serveUpsertReqDTOList) {
        //1.校验服务项是否为启用状态,不是启用状态不能新增
        ServeItem serveItem = serveItemMapper.selectById(serveUpsertReqDTO.getServeItemId());
        //如果服务项信息不存在或未启用
        if(ObjectUtil.isNull(serveItem) || serveItem.getActiveStatus()!= FoundationStatusEnum.ENABLE.getStatus()){
            throw new ForbiddenOperationException("该服务未启用无法添加到区域下使用");
        }

        //2.校验是否重复新增
        Integer count = lambdaQuery()
                .eq(Serve::getRegionId, serveUpsertReqDTO.getRegionId())
                .eq(Serve::getServeItemId, serveUpsertReqDTO.getServeItemId())
                .count();
        if(count>0){
            throw new ForbiddenOperationException(serveItem.getName()+"服务已存在");
        }

        //3.新增服务
        Serve serve = BeanUtil.toBean(serveUpsertReqDTO, Serve.class);
        Region region = regionMapper.selectById(serveUpsertReqDTO.getRegionId());
        serve.setCityCode(region.getCityCode());
        baseMapper.insert(serve);
    }

}

说明:

对于增、删、改类的接口通常会先进行入参校验,校验失败抛出异常,由异常处理器统一对异常进行处理。

我们抛出的异常是自定义异常类型,自定义的异常类型都继承了CommonException类型,在异常处理器中对此类型的异常进行处理。

异常处理器的源码在jzo2o-framework中,如下图:

通过@RestControllerAdvice注解加@ExceptionHandler注解实现,具体的原理是当controller抛出异常由DispatcherServlet统一拦截处理,再根据异常类型找到@ExceptionHandler标识方法去执行该方法进行异常处理。

1.1.2.3 controller

在controller方法中调用service接口添加区域服务。

java 复制代码
@PostMapping("/batch")
@ApiOperation("批量添加区域服务")
public void batch(@RequestBody List<ServeUpsertReqDTO> serveUpsertReqDTOList) {
    serveService.batchAdd(serveUpsertReqDTOList);
}

1.1.3 测试

我们通过前后端联调测试添加区域服务接口。

启动foundations服务和gateway服务。

通过cmd进入project-xzb-pc-admin-vue3-java目录启动前端项目

运行命令,启动前端工程

shell 复制代码
npm run dev 

因为代码是我们写的,我们在前后端联调时除了测试成功结果还要测试失败结果。

下边我们先测试成功结果。

进入运营管理端,点击"区域管理"菜单,点击"设置服务"

区域服务列表如下图:

点击添加服务

点击添加服务,如下图:

添加成功查询区域服务列表是否存在已添加的服务。

如果列表没有显示已添加的服务则需要进行排查,可以进入数据库直接查询serve表查看是否添加成功,如果后台的错误日志需要根据错误日志进行排查。

下边测试失败结果。

1.2 修改价格

1.2.1 接口定义

1.2.1.1 接口设计

根据界面原型设计传入参数类型、参数内容、响应结果内容。

进入修改界面

输入价格进行修改

传入参数内容:价格、区域服务ID(serve表主键)

根据id更新serve表的价格字段。

传入参数类型:form表单格式

响应结果内容可为空,前端根据状态码判断是否添加成功。

接口设计信息如下:

接口路径:PUT/foundations/operation/serve/{id}

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

1.2.1.2 接口定义-form表单

编写controller方法,HTTP方法使用PUT方式,代码如下:

PUT /foundations/operation/serve/{id}从url中接,用@PathVariable,id是从url中获取,而price是前端传过来了的,所以用 @RequestParam来接收。

java 复制代码
@PutMapping("/{id}")
@ApiOperation("区域服务价格修改")
@ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "服务id", required = true, dataTypeClass = Long.class),
        @ApiImplicitParam(name = "price", value = "价格", required = true, dataTypeClass = BigDecimal.class)
})
public void update( @PathVariable("id") Long id,
                    @RequestParam("price") BigDecimal price) {

}

1.2.2 接口开发

1.2.2.1 mapper

修改接口只向serve表更新数据所以使用mybatisplus提供的单表CRUD方法即可无需自定义mapper接口。

1.2.2.2 service

定义service接口:

java 复制代码
Serve update(Long id, BigDecimal price);

返回修改后的Serve类型有助于我们后期做缓存,就不用再查了。

定义service实现方法:

java 复制代码
@Override
@Transactional
public Serve update(Long id, BigDecimal price) {
    //1.更新服务价格
    boolean update = lambdaUpdate()
            .eq(Serve::getId, id)
            .set(Serve::getPrice, price)
            .update();
    if(!update){
        throw new CommonException("修改服务价格失败");
    }
    return baseMapper.selectById(id);
}
1.2.2.3 controller

在controller方法中调用service接口价格修改。

java 复制代码
@PutMapping("/{id}")
@ApiOperation("区域服务价格修改")
@ApiImplicitParams({
    @ApiImplicitParam(name = "id", value = "服务id", required = true, dataTypeClass = Long.class),
    @ApiImplicitParam(name = "price", value = "价格", required = true, dataTypeClass = BigDecimal.class)
})
public void update(@PathVariable("id") Long id,
          @RequestParam("price") BigDecimal price) {
  serveService.update(id, price);
}

1.2.3 测试

查看控制台

测试成功

1.3 服务上架

1.3.1 接口定义

1.3.1.1 接口设计

根据业务流程、界面原型进行设计。

在区域服务列表中点击"上架",此服务在该区域将生效,用户即可对该服务进行下单。

业务流程如下:

在serve表有一个售卖状态sale_status,服务上架后将状态更改为"上架",代码为2。

下边分析接口的传入参数类型、参数内容、响应结果内容。

传入参数内容:服务Id(serve表的主键),

传入参数类型:form表单格式

响应结果内容: 内容可为空,前端根据状态码判断是否添加成功。

注意:区分 服务id和服务项id,服务id即serve表的主键,服务项id即serve_item表的主键。

接口信息如下:

接口路径:PUT/foundations/operation/serve/onSale/{id}

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

1.3.1.2 接口定义-form表单格式

编写controller方法,HTTP方法使用PUT方式,代码如下:

java 复制代码
@PutMapping("/onSale/{id}")
@ApiOperation("区域服务上架")
@ApiImplicitParam(name = "id", value = "服务id", required = true, dataTypeClass = Long.class)
public void onSale(@PathVariable("id") Long id) {
    return;
}

1.3.2 接口开发

1.3.2.1 mapper

服务上架最终修改serve表的状态,所以使用mybatisplus提供的单表CRUD方法即可无需自定义mapper接口。

1.3.2.2 service

定义service接口:

java 复制代码
Serve onSale(Long id);

实现:

java 复制代码
@Override
@Transactional
public Serve onSale(Long id) {
    //1.校验服务是否存在
    Serve serve = baseMapper.selectById(id);
    if(ObjectUtil.isNull(serve)){
        throw new ForbiddenOperationException("区域服务不存在");
    }
    //2.校验服务状态是否为草稿或下架状态
    if(serve.getSaleStatus()!= FoundationStatusEnum.INIT.getStatus() || serve.getSaleStatus()!= FoundationStatusEnum.DISABLE.getStatus()){
        throw new ForbiddenOperationException("服务状态不为草稿或下架状态,无法上架");
    }
    //3.校验服务项是否为启用状态
    ServeItem serveItem = serveItemMapper.selectById(serve.getServeItemId());
    if(serveItem.getActiveStatus()!= FoundationStatusEnum.ENABLE.getStatus()){
        throw new ForbiddenOperationException("本服务所属的服务项未启用,无法上架");
    }
    //4.更新服务状态为上架
    boolean update = lambdaUpdate()
            .eq(Serve::getId, id)
            .set(Serve::getSaleStatus, FoundationStatusEnum.ENABLE.getStatus())
            .update();
    if(!update){
        throw new CommonException("服务上架失败");
    }
    return baseMapper.selectById(id);
}
1.3.2.3 controller
java 复制代码
@PutMapping("/onSale/{id}")
@ApiOperation("区域服务上架")
@ApiImplicitParam(name = "id", value = "服务id", required = true, dataTypeClass = Long.class)
public void onSale(@PathVariable("id") Long id) {
    serveService.onSale(id);
}

1.3.3 测试

上架成功

1.4 删除区域服务开发

1.4.1 接口定义

1.4.1.1 接口设计

根据业务流程、界面原型进行设计。

在区域服务列表中点击"删除",此服务在该区域将删除。

业务流程如下:

在serve表中删除该服务。

下边分析接口的传入参数类型、参数内容、响应结果内容。

传入参数内容:服务Id(serve表的主键),

传入参数类型:form表单格式

响应结果内容: 内容可为空,前端根据状态码判断是否添加成功。

注意:区分 服务id和服务项id,服务id即serve表的主键,服务项id即serve_item表的主键。

接口信息如下:

接口路径:DELETE/foundations/operation/serve/{id}

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

1.4.1.2 接口定义-form表单
java 复制代码
@DeleteMapping("/{id}")
@ApiOperation("区域服务删除")
@ApiImplicitParam(name = "id", value = "服务id", required = true, dataTypeClass = Long.class)
public void delete(@PathVariable("id") Long id) {
    return;
}

1.4.2 接口开发

1.4.2.1 mapper

服务上架最终修改serve表的状态,所以使用mybatisplus提供的单表CRUD方法即可无需自定义mapper接口。

1.4.2.2 service

定义service接口:

java 复制代码
void delete(Long id);

实现:

java 复制代码
@Override
@Transactional
public void delete(Long id) {
    //1.校验服务是否存在
    Serve serve = baseMapper.selectById(id);
    if(ObjectUtil.isNull(serve)){
        throw new ForbiddenOperationException("区域服务不存在");
    }
    //2.校验服务状态是否为草稿状态
    if(serve.getSaleStatus()!= FoundationStatusEnum.INIT.getStatus()){
        throw new ForbiddenOperationException("服务状态不为草稿状态,无法删除");
    }
    //3.删除服务
    baseMapper.deleteById(id);
}
1.4.2.3 controller
java 复制代码
@DeleteMapping("/{id}")
@ApiOperation("区域服务删除")
@ApiImplicitParam(name = "id", value = "服务id", required = true, dataTypeClass = Long.class)
public void delete(@PathVariable("id") Long id) {
    serveService.delete(id);
}

1.4.3 测试

1.5 区域服务下架开发

业务流程:

接口文档:

1.5.1 mapper

服务上架最终修改serve表的状态,所以使用mybatisplus提供的单表CRUD方法即可无需自定义mapper接口。

1.5.2 service

接口:

void offSale(Long id);

实现:

java 复制代码
@Override
@Transactional
public void offSale(Long id) {
    //1.校验服务是否存在
    Serve serve = baseMapper.selectById(id);
    if(ObjectUtil.isNull(serve)){
        throw new ForbiddenOperationException("区域服务不存在");
    }
    //2.校验服务状态是否为上架状态
    if(serve.getSaleStatus()!= FoundationStatusEnum.ENABLE.getStatus()){
        throw new ForbiddenOperationException("服务状态不为上架状态,无法下架");
    }
    //3.更新服务状态为下架
    boolean update = lambdaUpdate()
            .eq(Serve::getId, id)
            .set(Serve::getSaleStatus, FoundationStatusEnum.DISABLE.getStatus())
            .update();
    if(!update){
        throw new CommonException("服务下架失败");
    }
}

1.5.3 controller

java 复制代码
@PutMapping("/offSale/{id}")
@ApiOperation("区域服务下架")
@ApiImplicitParam(name = "id", value = "服务id", required = true, dataTypeClass = Long.class)
public void offSale(@PathVariable("id") Long id) {
    serveService.offSale(id);
}

1.5.4 测试

1.6 设置热门开发

要求:实现更新serve表的是否热门字段。

接口文档:

1.6.1 mapper

服务上架最终修改serve表的状态,所以使用mybatisplus提供的单表CRUD方法即可无需自定义mapper接口。

1.6.2 service

接口:

java 复制代码
Serve onHot(Long id);

实现:

java 复制代码
@Override
@Transactional
public Serve onHot(Long id) {
    //1.校验服务是否存在
    Serve serve = baseMapper.selectById(id);
    if(ObjectUtil.isNull(serve)){
        throw new ForbiddenOperationException("区域服务不存在");
    }
    //2.校验服务状态是否为上架状态
    if(serve.getSaleStatus()!= FoundationStatusEnum.ENABLE.getStatus()){
        throw new ForbiddenOperationException("服务状态不为上架状态,无法设置热门");
    }
    //3.更新服务状态为热门
    boolean update = lambdaUpdate()
            .eq(Serve::getId, id)
            .set(Serve::getIsHot, FoundationStatusEnum.ONHOT.getStatus())
            .update();
    if(!update){
        throw new CommonException("服务设置热门失败");
    }
    return baseMapper.selectById(id);
}

1.6.3 controller

java 复制代码
@PutMapping("/onHot/{id}")
@ApiOperation("区域服务设置热门")
@ApiImplicitParam(name = "id", value = "服务id", required = true, dataTypeClass = Long.class)
public void onHot(@PathVariable("id") Long id) {
    serveService.onHot(id);
}

1.6.4 测试

1.7 取消热门开发

要求:实现更新serve表的是否热门字段。

接口文档:

1.7.1 mapper

服务上架最终修改serve表的状态,所以使用mybatisplus提供的单表CRUD方法即可无需自定义mapper接口。

1.7.2 service

接口:

java 复制代码
Serve offHot(Long id);

实现:

java 复制代码
@Override
@Transactional
public Serve offHot(Long id) {
    //1.校验服务是否存在
    Serve serve = baseMapper.selectById(id);
    if(ObjectUtil.isNull(serve)){
        throw new ForbiddenOperationException("区域服务不存在");
    }
    //2.校验服务状态是否为上架状态
    if(serve.getSaleStatus()!= FoundationStatusEnum.ENABLE.getStatus()){
        throw new ForbiddenOperationException("服务状态不为上架状态,无法取消热门");
    }
    //3.更新服务状态为非热门
    boolean update = lambdaUpdate()
            .eq(Serve::getId, id)
            .set(Serve::getIsHot, FoundationStatusEnum.OFFHOT.getStatus())
            .update();
    if(!update){
        throw new CommonException("服务取消热门失败");
    }
    return baseMapper.selectById(id);
}

1.7.3 controller

java 复制代码
@PutMapping("/offHot/{id}")
@ApiOperation("区域服务取消热门")
@ApiImplicitParam(name = "id", value = "服务id", required = true, dataTypeClass = Long.class)
public void offHot(@PathVariable("id") Long id) {
    serveService.offHot(id);
}

1.7.4 测试

同1.6.4

1.8 启用区域功能完善

业务流程:

增加校验:区域下存在上架的服务方可启用。

1.8.1 创建按区域id和状态查询的mapper

在com.jzo2o.foundations.mapper.ServeMapper中创建

java 复制代码
List<ServeResDTO> queryServeListByRegionIdAndStatus(@Param("regionId") Long regionId, @Param("status") Integer status);

xml

xml 复制代码
<select id="queryServeListByRegionIdAndStatus"
        resultType="com.jzo2o.foundations.model.dto.response.ServeResDTO">
    SELECT
    st.id serve_type_id,
        si.NAME serve_item_name,
        s.update_time update_time,
        s.sale_status sale_status,
        si.id serve_item_id,
        si.reference_price reference_price,
        s.create_time create_time,
        s.region_id region_id,
        s.price price,
        s.id id,
        s.is_hot is_hot,
        st.NAME serve_type_name
    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
        region_id = #{regionId} AND sale_status = #{status}
</select>

1.8.2 增加校验逻辑

在com.jzo2o.foundations.service.impl.RegionServiceImpl#active方法中

java 复制代码
//如果需要启用区域,需要校验该区域下是否有上架的服务
List<ServeResDTO> serveResDTOS = serveMapper.queryServeListByRegionIdAndStatus(region.getId(), FoundationStatusEnum.ENABLE.getStatus());
if (serveResDTOS.size() == 0) {
    throw new ForbiddenOperationException("区域内无可用的上架服务,无法启用");
}

1.9 禁用区域功能完善

业务流程:

增加校验:区域下不存在上架的服务方可禁用。

1.9.1 增加校验逻辑

在com.jzo2o.foundations.service.impl.RegionServiceImpl#deactivate方法中

java 复制代码
List<ServeResDTO> serveResDTOS = serveMapper.queryServeListByRegionIdAndStatus(region.getId(), FoundationStatusEnum.ENABLE.getStatus());
if (serveResDTOS.size() > 0) {
    throw new ForbiddenOperationException("区域内有上架服务,无法禁用");
}

1.10 禁用服务项功能完善

业务流程

1.10.1 创建按服务项id和状态查询的mapper

在com.jzo2o.foundations.mapper.ServeMapper中创建

java 复制代码
List<ServeResDTO> queryServeListByServeItemIdAndStatus(@Param("serveItemId") Long serveItemId, @Param("status") Integer status);

xml

xml 复制代码
<select id="queryServeListByServeItemIdAndStatus"
        resultType="com.jzo2o.foundations.model.dto.response.ServeResDTO">
    SELECT
        st.id serve_type_id,
        si.NAME serve_item_name,
        s.update_time update_time,
        s.sale_status sale_status,
        si.id serve_item_id,
        si.reference_price reference_price,
        s.create_time create_time,
        s.region_id region_id,
        s.price price,
        s.id id,
        s.is_hot is_hot,
        st.NAME serve_type_name
    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
        serve_item_id = #{serveItemId} AND sale_status = #{status}
</select>

1.10.2 增加校验逻辑

在com.jzo2o.foundations.service.impl.ServeItemServiceImpl#deactivate中

java 复制代码
//有区域在使用该服务将无法禁用(存在关联的区域服务且状态为上架表示有区域在使用该服务项)
List<ServeResDTO> serveResDTOS = serveMapper.queryServeListByServeItemIdAndStatus(id, FoundationStatusEnum.ENABLE.getStatus());
if (serveResDTOS.size() > 0) {
    throw new ForbiddenOperationException("存在关联的区域服务且状态为上架表示有区域在使用该服务项");
}
相关推荐
一直学习永不止步3 分钟前
LeetCode题练习与总结:赎金信--383
java·数据结构·算法·leetcode·字符串·哈希表·计数
尘浮生6 分钟前
Java项目实战II基于Spring Boot的光影视频平台(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·maven·intellij-idea
尚学教辅学习资料14 分钟前
基于SpringBoot的医药管理系统+LW示例参考
java·spring boot·后端·java毕业设计·医药管理
雷神乐乐30 分钟前
File.separator与File.separatorChar的区别
java·路径分隔符
小刘|35 分钟前
《Java 实现希尔排序:原理剖析与代码详解》
java·算法·排序算法
逊嘘1 小时前
【Java语言】抽象类与接口
java·开发语言·jvm
morris1311 小时前
【SpringBoot】Xss的常见攻击方式与防御手段
java·spring boot·xss·csp
龙哥说跨境1 小时前
如何利用指纹浏览器爬虫绕过Cloudflare的防护?
服务器·网络·python·网络爬虫
monkey_meng1 小时前
【Rust中多线程同步机制】
开发语言·redis·后端·rust