Commit 2fcfebc7c5b26215375912fb45a2cbd165b04de9
1 parent
2d49ac27
feat(mes): 更新物料库存模块,优化物料查询逻辑并新增工作站和库区数量统计功能
Showing
9 changed files
with
95 additions
and
58 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockPageReqVO.java
| ... | ... | @@ -15,11 +15,8 @@ public class MesWmMaterialStockPageReqVO extends PageParam { |
| 15 | 15 | @Schema(description = "物料分类编号", example = "1") |
| 16 | 16 | private Long itemTypeId; |
| 17 | 17 | |
| 18 | - @Schema(description = "物料编码", example = "M001") | |
| 19 | - private String itemCode; | |
| 20 | - | |
| 21 | - @Schema(description = "物料名称", example = "钢板") | |
| 22 | - private String itemName; | |
| 18 | + @Schema(description = "物料编号", example = "1") | |
| 19 | + private Long itemId; | |
| 23 | 20 | |
| 24 | 21 | @Schema(description = "批次号", example = "B20260101") |
| 25 | 22 | private String batchCode; | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/workstation/MesMdWorkstationService.java
| ... | ... | @@ -61,4 +61,28 @@ public interface MesMdWorkstationService { |
| 61 | 61 | */ |
| 62 | 62 | List<MesMdWorkstationDO> getWorkstationListByStatus(Integer status); |
| 63 | 63 | |
| 64 | + /** | |
| 65 | + * 获得指定仓库下的工作站数量 | |
| 66 | + * | |
| 67 | + * @param warehouseId 仓库编号 | |
| 68 | + * @return 工作站数量 | |
| 69 | + */ | |
| 70 | + Long getWorkstationCountByWarehouseId(Long warehouseId); | |
| 71 | + | |
| 72 | + /** | |
| 73 | + * 获得指定库区下的工作站数量 | |
| 74 | + * | |
| 75 | + * @param locationId 库区编号 | |
| 76 | + * @return 工作站数量 | |
| 77 | + */ | |
| 78 | + Long getWorkstationCountByLocationId(Long locationId); | |
| 79 | + | |
| 80 | + /** | |
| 81 | + * 获得指定库位下的工作站数量 | |
| 82 | + * | |
| 83 | + * @param areaId 库位编号 | |
| 84 | + * @return 工作站数量 | |
| 85 | + */ | |
| 86 | + Long getWorkstationCountByAreaId(Long areaId); | |
| 87 | + | |
| 64 | 88 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/workstation/MesMdWorkstationServiceImpl.java
| ... | ... | @@ -212,4 +212,19 @@ public class MesMdWorkstationServiceImpl implements MesMdWorkstationService { |
| 212 | 212 | return workstationMapper.selectListByStatus(status); |
| 213 | 213 | } |
| 214 | 214 | |
| 215 | + @Override | |
| 216 | + public Long getWorkstationCountByWarehouseId(Long warehouseId) { | |
| 217 | + return workstationMapper.selectCountByWarehouseId(warehouseId); | |
| 218 | + } | |
| 219 | + | |
| 220 | + @Override | |
| 221 | + public Long getWorkstationCountByLocationId(Long locationId) { | |
| 222 | + return workstationMapper.selectCountByLocationId(locationId); | |
| 223 | + } | |
| 224 | + | |
| 225 | + @Override | |
| 226 | + public Long getWorkstationCountByAreaId(Long areaId) { | |
| 227 | + return workstationMapper.selectCountByAreaId(areaId); | |
| 228 | + } | |
| 229 | + | |
| 215 | 230 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.mes.service.wm.materialstock; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | -import cn.hutool.core.util.StrUtil; | |
| 5 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | |
| 6 | 6 | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockPageReqVO; |
| 7 | 7 | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockSaveReqVO; |
| 8 | -import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; | |
| 9 | 8 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO; |
| 10 | 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO; |
| 11 | -import cn.iocoder.yudao.module.mes.dal.mysql.md.item.MesMdItemMapper; | |
| 12 | 10 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock.MesWmMaterialStockMapper; |
| 13 | 11 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemTypeService; |
| 14 | -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | |
| 15 | 12 | import jakarta.annotation.Resource; |
| 16 | 13 | import org.springframework.stereotype.Service; |
| 17 | 14 | import org.springframework.validation.annotation.Validated; |
| ... | ... | @@ -35,9 +32,6 @@ public class MesWmMaterialStockServiceImpl implements MesWmMaterialStockService |
| 35 | 32 | @Resource |
| 36 | 33 | private MesMdItemTypeService itemTypeService; |
| 37 | 34 | |
| 38 | - @Resource | |
| 39 | - private MesMdItemMapper itemMapper; | |
| 40 | - | |
| 41 | 35 | @Override |
| 42 | 36 | public MesWmMaterialStockDO getMaterialStock(Long id) { |
| 43 | 37 | return materialStockMapper.selectById(id); |
| ... | ... | @@ -54,7 +48,7 @@ public class MesWmMaterialStockServiceImpl implements MesWmMaterialStockService |
| 54 | 48 | |
| 55 | 49 | @Override |
| 56 | 50 | public PageResult<MesWmMaterialStockDO> getMaterialStockPage(MesWmMaterialStockPageReqVO pageReqVO) { |
| 57 | - // 1. 解析 itemTypeId:包含子分类 | |
| 51 | + // 1.1 解析 itemTypeId:包含子分类 | |
| 58 | 52 | Set<Long> itemTypeIds = null; |
| 59 | 53 | if (pageReqVO.getItemTypeId() != null) { |
| 60 | 54 | itemTypeIds = new HashSet<>(); |
| ... | ... | @@ -62,20 +56,13 @@ public class MesWmMaterialStockServiceImpl implements MesWmMaterialStockService |
| 62 | 56 | List<MesMdItemTypeDO> children = itemTypeService.getItemTypeChildrenList(pageReqVO.getItemTypeId()); |
| 63 | 57 | itemTypeIds.addAll(convertSet(children, MesMdItemTypeDO::getId)); |
| 64 | 58 | } |
| 65 | - | |
| 66 | - // 2. 解析 itemCode/itemName:查 md_item 找匹配的 itemId 集合 | |
| 59 | + // 1.2 解析 itemId | |
| 67 | 60 | Set<Long> itemIds = null; |
| 68 | - if (StrUtil.isNotBlank(pageReqVO.getItemCode()) || StrUtil.isNotBlank(pageReqVO.getItemName())) { | |
| 69 | - List<MesMdItemDO> matchingItems = itemMapper.selectList(new LambdaQueryWrapperX<MesMdItemDO>() | |
| 70 | - .eqIfPresent(MesMdItemDO::getCode, pageReqVO.getItemCode()) | |
| 71 | - .likeIfPresent(MesMdItemDO::getName, pageReqVO.getItemName())); | |
| 72 | - if (matchingItems.isEmpty()) { | |
| 73 | - return PageResult.empty(); | |
| 74 | - } | |
| 75 | - itemIds = convertSet(matchingItems, MesMdItemDO::getId); | |
| 61 | + if (pageReqVO.getItemId() != null) { | |
| 62 | + itemIds = SetUtils.asSet(pageReqVO.getItemId()); | |
| 76 | 63 | } |
| 77 | 64 | |
| 78 | - // 3. 分页查询 | |
| 65 | + // 2. 分页查询 | |
| 79 | 66 | return materialStockMapper.selectPage(pageReqVO, itemTypeIds, itemIds); |
| 80 | 67 | } |
| 81 | 68 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/warehouse/MesWmWarehouseAreaService.java
| ... | ... | @@ -83,4 +83,12 @@ public interface MesWmWarehouseAreaService { |
| 83 | 83 | return convertMap(getWarehouseAreaList(ids), MesWmWarehouseAreaDO::getId); |
| 84 | 84 | } |
| 85 | 85 | |
| 86 | + /** | |
| 87 | + * 获得指定库区下的库位数量 | |
| 88 | + * | |
| 89 | + * @param locationId 库区编号 | |
| 90 | + * @return 库位数量 | |
| 91 | + */ | |
| 92 | + Long getWarehouseAreaCountByLocationId(Long locationId); | |
| 93 | + | |
| 86 | 94 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/warehouse/MesWmWarehouseAreaServiceImpl.java
| ... | ... | @@ -7,9 +7,9 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | 7 | import cn.iocoder.yudao.module.mes.controller.admin.wm.warehouse.vo.area.MesWmWarehouseAreaPageReqVO; |
| 8 | 8 | import cn.iocoder.yudao.module.mes.controller.admin.wm.warehouse.vo.area.MesWmWarehouseAreaSaveReqVO; |
| 9 | 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO; |
| 10 | -import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationMapper; | |
| 11 | -import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock.MesWmMaterialStockMapper; | |
| 12 | 10 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.warehouse.MesWmWarehouseAreaMapper; |
| 11 | +import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService; | |
| 12 | +import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; | |
| 13 | 13 | import jakarta.annotation.Resource; |
| 14 | 14 | import org.springframework.stereotype.Service; |
| 15 | 15 | import org.springframework.validation.annotation.Validated; |
| ... | ... | @@ -21,7 +21,6 @@ import java.util.List; |
| 21 | 21 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 22 | 22 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| 23 | 23 | |
| 24 | -// TODO @AI:不应该直接跨模块调用 mapper,通过他们的 service 操作 | |
| 25 | 24 | /** |
| 26 | 25 | * MES 库位 Service 实现类 |
| 27 | 26 | */ |
| ... | ... | @@ -33,11 +32,9 @@ public class MesWmWarehouseAreaServiceImpl implements MesWmWarehouseAreaService |
| 33 | 32 | private MesWmWarehouseAreaMapper areaMapper; |
| 34 | 33 | |
| 35 | 34 | @Resource |
| 36 | - private MesMdWorkstationMapper workstationMapper; | |
| 37 | - | |
| 35 | + private MesMdWorkstationService workstationService; | |
| 38 | 36 | @Resource |
| 39 | - private MesWmMaterialStockMapper materialStockMapper; | |
| 40 | - | |
| 37 | + private MesWmMaterialStockService materialStockService; | |
| 41 | 38 | @Resource |
| 42 | 39 | private MesWmWarehouseLocationService locationService; |
| 43 | 40 | |
| ... | ... | @@ -75,11 +72,11 @@ public class MesWmWarehouseAreaServiceImpl implements MesWmWarehouseAreaService |
| 75 | 72 | // 校验存在 |
| 76 | 73 | validateWarehouseAreaExists(id); |
| 77 | 74 | // 校验是否被工作站引用 |
| 78 | - if (workstationMapper.selectCountByAreaId(id) > 0) { | |
| 75 | + if (workstationService.getWorkstationCountByAreaId(id) > 0) { | |
| 79 | 76 | throw exception(WM_WAREHOUSE_AREA_HAS_WORKSTATION); |
| 80 | 77 | } |
| 81 | 78 | // 校验是否有库存记录 |
| 82 | - if (materialStockMapper.selectCountByAreaId(id) > 0) { | |
| 79 | + if (materialStockService.getMaterialStockCountByAreaId(id) > 0) { | |
| 83 | 80 | throw exception(WM_WAREHOUSE_AREA_HAS_MATERIAL_STOCK); |
| 84 | 81 | } |
| 85 | 82 | |
| ... | ... | @@ -138,4 +135,9 @@ public class MesWmWarehouseAreaServiceImpl implements MesWmWarehouseAreaService |
| 138 | 135 | return areaMapper.selectListByIds(ids); |
| 139 | 136 | } |
| 140 | 137 | |
| 138 | + @Override | |
| 139 | + public Long getWarehouseAreaCountByLocationId(Long locationId) { | |
| 140 | + return areaMapper.selectCountByLocationId(locationId); | |
| 141 | + } | |
| 142 | + | |
| 141 | 143 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/warehouse/MesWmWarehouseLocationService.java
| ... | ... | @@ -83,4 +83,12 @@ public interface MesWmWarehouseLocationService { |
| 83 | 83 | return convertMap(getWarehouseLocationList(ids), MesWmWarehouseLocationDO::getId); |
| 84 | 84 | } |
| 85 | 85 | |
| 86 | + /** | |
| 87 | + * 获得指定仓库下的库区数量 | |
| 88 | + * | |
| 89 | + * @param warehouseId 仓库编号 | |
| 90 | + * @return 库区数量 | |
| 91 | + */ | |
| 92 | + Long getWarehouseLocationCountByWarehouseId(Long warehouseId); | |
| 93 | + | |
| 86 | 94 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/warehouse/MesWmWarehouseLocationServiceImpl.java
| ... | ... | @@ -7,10 +7,9 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | 7 | import cn.iocoder.yudao.module.mes.controller.admin.wm.warehouse.vo.location.MesWmWarehouseLocationPageReqVO; |
| 8 | 8 | import cn.iocoder.yudao.module.mes.controller.admin.wm.warehouse.vo.location.MesWmWarehouseLocationSaveReqVO; |
| 9 | 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO; |
| 10 | -import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationMapper; | |
| 11 | -import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock.MesWmMaterialStockMapper; | |
| 12 | -import cn.iocoder.yudao.module.mes.dal.mysql.wm.warehouse.MesWmWarehouseAreaMapper; | |
| 13 | 10 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.warehouse.MesWmWarehouseLocationMapper; |
| 11 | +import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService; | |
| 12 | +import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; | |
| 14 | 13 | import jakarta.annotation.Resource; |
| 15 | 14 | import org.springframework.stereotype.Service; |
| 16 | 15 | import org.springframework.validation.annotation.Validated; |
| ... | ... | @@ -22,7 +21,6 @@ import java.util.List; |
| 22 | 21 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 23 | 22 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| 24 | 23 | |
| 25 | -// TODO @AI:不应该直接跨模块调用 mapper,通过他们的 service 操作 | |
| 26 | 24 | /** |
| 27 | 25 | * MES 库区 Service 实现类 |
| 28 | 26 | */ |
| ... | ... | @@ -34,14 +32,11 @@ public class MesWmWarehouseLocationServiceImpl implements MesWmWarehouseLocation |
| 34 | 32 | private MesWmWarehouseLocationMapper locationMapper; |
| 35 | 33 | |
| 36 | 34 | @Resource |
| 37 | - private MesWmWarehouseAreaMapper areaMapper; | |
| 38 | - | |
| 35 | + private MesWmWarehouseAreaService areaService; | |
| 39 | 36 | @Resource |
| 40 | - private MesMdWorkstationMapper workstationMapper; | |
| 41 | - | |
| 37 | + private MesMdWorkstationService workstationService; | |
| 42 | 38 | @Resource |
| 43 | - private MesWmMaterialStockMapper materialStockMapper; | |
| 44 | - | |
| 39 | + private MesWmMaterialStockService materialStockService; | |
| 45 | 40 | @Resource |
| 46 | 41 | private MesWmWarehouseService warehouseService; |
| 47 | 42 | |
| ... | ... | @@ -79,15 +74,15 @@ public class MesWmWarehouseLocationServiceImpl implements MesWmWarehouseLocation |
| 79 | 74 | // 校验存在 |
| 80 | 75 | validateWarehouseLocationExists(id); |
| 81 | 76 | // 校验是否有库位 |
| 82 | - if (areaMapper.selectCountByLocationId(id) > 0) { | |
| 77 | + if (areaService.getWarehouseAreaCountByLocationId(id) > 0) { | |
| 83 | 78 | throw exception(WM_WAREHOUSE_LOCATION_HAS_AREA); |
| 84 | 79 | } |
| 85 | 80 | // 校验是否被工作站引用 |
| 86 | - if (workstationMapper.selectCountByLocationId(id) > 0) { | |
| 81 | + if (workstationService.getWorkstationCountByLocationId(id) > 0) { | |
| 87 | 82 | throw exception(WM_WAREHOUSE_LOCATION_HAS_WORKSTATION); |
| 88 | 83 | } |
| 89 | 84 | // 校验是否有库存记录 |
| 90 | - if (materialStockMapper.selectCountByLocationId(id) > 0) { | |
| 85 | + if (materialStockService.getMaterialStockCountByLocationId(id) > 0) { | |
| 91 | 86 | throw exception(WM_WAREHOUSE_LOCATION_HAS_MATERIAL_STOCK); |
| 92 | 87 | } |
| 93 | 88 | |
| ... | ... | @@ -146,4 +141,9 @@ public class MesWmWarehouseLocationServiceImpl implements MesWmWarehouseLocation |
| 146 | 141 | return locationMapper.selectListByIds(ids); |
| 147 | 142 | } |
| 148 | 143 | |
| 144 | + @Override | |
| 145 | + public Long getWarehouseLocationCountByWarehouseId(Long warehouseId) { | |
| 146 | + return locationMapper.selectCountByWarehouseId(warehouseId); | |
| 147 | + } | |
| 148 | + | |
| 149 | 149 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/warehouse/MesWmWarehouseServiceImpl.java
| ... | ... | @@ -7,10 +7,9 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | 7 | import cn.iocoder.yudao.module.mes.controller.admin.wm.warehouse.vo.MesWmWarehousePageReqVO; |
| 8 | 8 | import cn.iocoder.yudao.module.mes.controller.admin.wm.warehouse.vo.MesWmWarehouseSaveReqVO; |
| 9 | 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO; |
| 10 | -import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationMapper; | |
| 11 | -import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock.MesWmMaterialStockMapper; | |
| 12 | -import cn.iocoder.yudao.module.mes.dal.mysql.wm.warehouse.MesWmWarehouseLocationMapper; | |
| 13 | 10 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.warehouse.MesWmWarehouseMapper; |
| 11 | +import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService; | |
| 12 | +import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; | |
| 14 | 13 | import jakarta.annotation.Resource; |
| 15 | 14 | import org.springframework.stereotype.Service; |
| 16 | 15 | import org.springframework.validation.annotation.Validated; |
| ... | ... | @@ -22,7 +21,6 @@ import java.util.List; |
| 22 | 21 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 23 | 22 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| 24 | 23 | |
| 25 | -// TODO @AI:不应该直接跨模块调用 mapper,通过他们的 service 操作 | |
| 26 | 24 | /** |
| 27 | 25 | * MES 仓库 Service 实现类 |
| 28 | 26 | */ |
| ... | ... | @@ -34,13 +32,11 @@ public class MesWmWarehouseServiceImpl implements MesWmWarehouseService { |
| 34 | 32 | private MesWmWarehouseMapper warehouseMapper; |
| 35 | 33 | |
| 36 | 34 | @Resource |
| 37 | - private MesWmWarehouseLocationMapper locationMapper; | |
| 38 | - | |
| 35 | + private MesWmWarehouseLocationService locationService; | |
| 39 | 36 | @Resource |
| 40 | - private MesMdWorkstationMapper workstationMapper; | |
| 41 | - | |
| 37 | + private MesMdWorkstationService workstationService; | |
| 42 | 38 | @Resource |
| 43 | - private MesWmMaterialStockMapper materialStockMapper; | |
| 39 | + private MesWmMaterialStockService materialStockService; | |
| 44 | 40 | |
| 45 | 41 | @Override |
| 46 | 42 | public Long createWarehouse(MesWmWarehouseSaveReqVO createReqVO) { |
| ... | ... | @@ -74,15 +70,15 @@ public class MesWmWarehouseServiceImpl implements MesWmWarehouseService { |
| 74 | 70 | // 校验存在 |
| 75 | 71 | validateWarehouseExists(id); |
| 76 | 72 | // 校验是否有库区 |
| 77 | - if (locationMapper.selectCountByWarehouseId(id) > 0) { | |
| 73 | + if (locationService.getWarehouseLocationCountByWarehouseId(id) > 0) { | |
| 78 | 74 | throw exception(WM_WAREHOUSE_HAS_LOCATION); |
| 79 | 75 | } |
| 80 | 76 | // 校验是否被工作站引用 |
| 81 | - if (workstationMapper.selectCountByWarehouseId(id) > 0) { | |
| 77 | + if (workstationService.getWorkstationCountByWarehouseId(id) > 0) { | |
| 82 | 78 | throw exception(WM_WAREHOUSE_HAS_WORKSTATION); |
| 83 | 79 | } |
| 84 | 80 | // 校验是否有库存记录 |
| 85 | - if (materialStockMapper.selectCountByWarehouseId(id) > 0) { | |
| 81 | + if (materialStockService.getMaterialStockCountByWarehouseId(id) > 0) { | |
| 86 | 82 | throw exception(WM_WAREHOUSE_HAS_MATERIAL_STOCK); |
| 87 | 83 | } |
| 88 | 84 | ... | ... |