# EngineeringRequestSelectOptionController.java

    package cloud.wconnect.frontoffice.controller.engineeringrequest;

    import cloud.wconnect.commonlib.annotation.ApiId;
    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.component.SessionContext;
    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.exception.ForbiddenException;
    import cloud.wconnect.commonlib.pojo.dto.ListPagedDTO;
    import cloud.wconnect.frontoffice.entity.engineeringrequest.EngineeringRequestArea;
    import cloud.wconnect.frontoffice.entity.engineeringrequest.EngineeringRequestIssue;
    import cloud.wconnect.frontoffice.entity.engineeringrequest.EngineeringRequestItem;
    import cloud.wconnect.frontoffice.entity.engineeringrequest.EngineeringRequestLocation;
    import cloud.wconnect.frontoffice.pojo.dto.engineeringrequest.*;
    import cloud.wconnect.frontoffice.service.engineeringrequest.*;
    import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    import jakarta.validation.Valid;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;

    import java.util.Collections;
    import java.util.List;
    import java.util.Map;
    import java.util.Objects;

    /**
     * 控制层：Engineering Request Select Option
     *
     * @author yyt
     * 2023/5/12
     */
    @RestController
    @RequestMapping("/engineering-request")
    public class EngineeringRequestSelectOptionController {

        @Autowired
        private IEngineeringRequestLocationService engineeringRequestLocationService;
        @Autowired
        private IEngineeringRequestAreaService engineeringRequestAreaService;
        @Autowired
        private IEngineeringRequestItemService engineeringRequestItemService;
        @Autowired
        private IEngineeringRequestIssueService engineeringRequestIssueService;
        @Autowired
        private IEngineeringRequestService engineeringRequestService;
        @Autowired
        private SessionContext sessionContext;
        @Autowired
        private BeanMapper beanMapper;

        /**
         * 获取 location 列表
         *
         * @param property 资产标识
         * @param query    搜索条件
         * @return location 列表
         * @author yyt
         * @date 2023/5/12
         */
        @ApiId(289)
        @GetMapping("/location")
        public ListPagedDTO<LocationDTO> listLocation(String property, SelectOptionQuery query) {
            Integer propertyId = sessionContext.getPropertyId(property);

            if (Objects.nonNull(query.getPage()) && Objects.nonNull(query.getSize())) {
                query.setPropertyId(propertyId);
                Page<EngineeringRequestLocation> page = engineeringRequestLocationService.page(query);
                return new ListPagedDTO<>(page.getTotal(), beanMapper.mapList(page.getRecords(), LocationDTO.class));
            } else {
                List<EngineeringRequestLocation> locations = engineeringRequestLocationService.listByCondition(propertyId, query);
                return new ListPagedDTO<>(locations.size(), beanMapper.mapList(locations, LocationDTO.class));
            }
        }

        /**
         * 新增 location
         *
         * @param property    资产标识
         * @param locationDTO location
         * @return {}
         * @author yyt
         * @date 2023/5/12
         */
        @ApiId(290)
        @PostMapping("/location")
        public Map addLocation(String property, @Valid @RequestBody LocationDTO locationDTO) {
            Integer propertyId = sessionContext.getPropertyId(property);

            engineeringRequestLocationService.checkExist(propertyId, locationDTO.getName(), null);

            engineeringRequestLocationService.save(propertyId, locationDTO, sessionContext.getLoginUserId());

            return Collections.emptyMap();
        }

        /**
         * 编辑 location
         *
         * @param id          location id
         * @param property    资产标识
         * @param locationDTO location 信息
         * @return {}
         * @author yyt
         * @date 2023/5/12
         */
        @ApiId(291)
        @PutMapping("/location/{id:\\d+}")
        public Map updateLocation(@PathVariable int id, String property, @Valid @RequestBody LocationDTO locationDTO) {
            EngineeringRequestLocation location = engineeringRequestLocationService.checkExist(id);

            Integer propertyId = sessionContext.getPropertyId(property);
            checkLocationPropertySame(location, propertyId);

            engineeringRequestLocationService.checkExist(propertyId, locationDTO.getName(), id);

            engineeringRequestLocationService.update(id, locationDTO, sessionContext.getLoginUserId());

            return Collections.emptyMap();
        }

        /**
         * 删除 location
         *
         * @param id       location id
         * @param property 资产标识
         * @return {}
         * @author yyt
         * @date 2023/5/12
         */
        @ApiId(292)
        @DeleteMapping("/location/{id:\\d+}")
        public Map deleteLocation(@PathVariable int id, String property) {
            EngineeringRequestLocation location = engineeringRequestLocationService.checkExist(id);

            Integer propertyId = sessionContext.getPropertyId(property);
            checkLocationPropertySame(location, propertyId);

            engineeringRequestService.checkLocationUsed(propertyId, id);

            engineeringRequestLocationService.delete(location);

            return Collections.emptyMap();
        }

        /**
         * 获取 area 列表
         *
         * @param id       location id
         * @param query    搜索条件
         * @param property 资产标识
         * @return area 列表
         * @author yyt
         * @date 2023/5/12
         */
        @ApiId(293)
        @GetMapping("/location/{id:\\d+}/area")
        public ListPagedDTO<AreaDTO> listArea(@PathVariable int id, String property, SelectOptionQuery query) {
            EngineeringRequestLocation location = engineeringRequestLocationService.checkExist(id);

            Integer propertyId = sessionContext.getPropertyId(property);
            checkLocationPropertySame(location, propertyId);

            if (Objects.nonNull(query.getPage()) && Objects.nonNull(query.getSize())) {
                query.setPropertyId(propertyId);
                query.setLocationId(id);
                Page<EngineeringRequestArea> page = engineeringRequestAreaService.page(query);
                return new ListPagedDTO<>(page.getTotal(), beanMapper.mapList(page.getRecords(), AreaDTO.class));
            } else {
                List<EngineeringRequestArea> areas = engineeringRequestAreaService.listByCondition(propertyId, id, query);
                return new ListPagedDTO<>(areas.size(), beanMapper.mapList(areas, AreaDTO.class));
            }
        }

        /**
         * 新增 area
         *
         * @param id       location id
         * @param property 资产标识
         * @param areaDTO  area
         * @return {}
         * @author yyt
         * @date 2023/5/12
         */
        @ApiId(294)
        @PostMapping("/location/{id:\\d+}/area")
        public Map addArea(@PathVariable int id, String property, @Valid @RequestBody AreaDTO areaDTO) {
            Integer propertyId = sessionContext.getPropertyId(property);

            EngineeringRequestLocation location = engineeringRequestLocationService.checkExist(id);
            checkLocationPropertySame(location, propertyId);

            engineeringRequestAreaService.checkExist(propertyId, id, areaDTO.getName(), null);

            engineeringRequestAreaService.save(propertyId, id, areaDTO, sessionContext.getLoginUserId());

            return Collections.emptyMap();
        }

        /**
         * 编辑 area
         *
         * @param lid      location id
         * @param aid      area id
         * @param property 资产标识
         * @param areaDTO  area 信息
         * @return {}
         * @author yyt
         * @date 2023/5/12
         */
        @ApiId(295)
        @PutMapping("/location/{lid:\\d+}/area/{aid:\\d+}")
        public Map updateArea(@PathVariable int lid, @PathVariable int aid, String property, @Valid @RequestBody AreaDTO areaDTO) {
            EngineeringRequestLocation location = engineeringRequestLocationService.checkExist(lid);

            Integer propertyId = sessionContext.getPropertyId(property);
            checkLocationPropertySame(location, propertyId);

            EngineeringRequestArea area = engineeringRequestAreaService.checkExist(lid, aid);
            checkAreaPropertySame(area, propertyId);
            checkAreaBelongLocation(area, location);

            engineeringRequestAreaService.checkExist(propertyId, lid, areaDTO.getName(), aid);

            engineeringRequestAreaService.update(aid, areaDTO, sessionContext.getLoginUserId());

            return Collections.emptyMap();
        }

        /**
         * 删除 area
         *
         * @param lid       location id
         * @param aid       area id
         * @param property 资产标识
         * @return {}
         * @author yyt
         * @date 2023/5/12
         */
        @ApiId(296)
        @DeleteMapping("/location/{lid:\\d+}/area/{aid:\\d+}")
        public Map deleteArea(@PathVariable int lid, @PathVariable int aid, String property) {
            EngineeringRequestLocation location = engineeringRequestLocationService.checkExist(lid);

            Integer propertyId = sessionContext.getPropertyId(property);
            checkLocationPropertySame(location, propertyId);

            EngineeringRequestArea area = engineeringRequestAreaService.checkExist(lid, aid);
            checkAreaPropertySame(area, propertyId);
            checkAreaBelongLocation(area, location);

            engineeringRequestService.checkAreaUsed(propertyId, area.getId());

            engineeringRequestAreaService.delete(area);

            return Collections.emptyMap();
        }

        /**
         * 获取 item 列表
         *
         * @param lid      location id
         * @param aid      area id
         * @param property 资产标识
         * @param query    搜索条件
         * @return item 列表
         * @author yyt
         * @date 2023/5/12
         */
        @ApiId(297)
        @GetMapping("/location/{lid:\\d+}/area/{aid:\\d+}/item")
        public ListPagedDTO<ItemDTO> listItem(@PathVariable int lid, @PathVariable int aid, String property,
                                              SelectOptionQuery query) {
            Integer propertyId = sessionContext.getPropertyId(property);

            EngineeringRequestLocation location = engineeringRequestLocationService.checkExist(lid);
            checkLocationPropertySame(location, propertyId);

            EngineeringRequestArea area = engineeringRequestAreaService.checkExist(lid, aid);
            checkAreaPropertySame(area, propertyId);
            checkAreaBelongLocation(area, location);

            if (Objects.nonNull(query.getPage()) && Objects.nonNull(query.getSize())) {
                query.setPropertyId(propertyId);
                query.setLocationId(lid);
                query.setAreaId(aid);
                Page<EngineeringRequestItem> page = engineeringRequestItemService.page(query);
                return new ListPagedDTO<>(page.getTotal(), beanMapper.mapList(page.getRecords(), ItemDTO.class));
            } else {
                List<EngineeringRequestItem> items = engineeringRequestItemService.listByCondition(propertyId, lid, aid, query);
                return new ListPagedDTO<>(items.size(), beanMapper.mapList(items, ItemDTO.class));
            }
        }

        /**
         * 新增 item
         *
         * @param lid       location id
         * @param aid       area id
         * @param property 资产标识
         * @param itemDTO  item
         * @return {}
         * @author yyt
         * @date 2023/5/12
         */
        @ApiId(298)
        @PostMapping("/location/{lid:\\d+}/area/{aid:\\d+}/item")
        public Map addItem(@PathVariable int lid, @PathVariable int aid, String property, @Valid @RequestBody ItemDTO itemDTO) {
            Integer propertyId = sessionContext.getPropertyId(property);

            EngineeringRequestLocation location = engineeringRequestLocationService.checkExist(lid);
            checkLocationPropertySame(location, propertyId);

            EngineeringRequestArea area = engineeringRequestAreaService.checkExist(lid, aid);
            checkAreaPropertySame(area, propertyId);
            checkAreaBelongLocation(area, location);

            engineeringRequestItemService.checkExist(propertyId, lid, aid, itemDTO.getGroupName(), itemDTO.getName(), null);

            engineeringRequestItemService.save(propertyId, lid, aid, itemDTO, sessionContext.getLoginUserId());

            return Collections.emptyMap();
        }

        /**
         * 编辑 item
         *
         * @param lid      location id
         * @param aid      area id
         * @param id       item id
         * @param property 资产标识
         * @param itemDTO  location 信息
         * @return {}
         * @author yyt
         * @date 2023/5/12
         */
        @ApiId(299)
        @PutMapping("/location/{lid:\\d+}/area/{aid:\\d+}/item/{id:\\d+}")
        public Map updateItem(@PathVariable int lid, @PathVariable int aid, @PathVariable int id, String property,
                              @Valid @RequestBody ItemDTO itemDTO) {
            EngineeringRequestLocation location = engineeringRequestLocationService.checkExist(lid);

            Integer propertyId = sessionContext.getPropertyId(property);
            checkLocationPropertySame(location, propertyId);

            EngineeringRequestArea area = engineeringRequestAreaService.checkExist(lid, aid);
            checkAreaPropertySame(area, propertyId);
            checkAreaBelongLocation(area, location);

            EngineeringRequestItem item = engineeringRequestItemService.checkExist(lid, aid, id);
            checkItemPropertySame(item, propertyId);
            checkItemBelongArea(item, area);

            engineeringRequestItemService.checkExist(propertyId, lid, aid, itemDTO.getGroupName(), itemDTO.getName(), id);

            engineeringRequestItemService.update(id, itemDTO, sessionContext.getLoginUserId());

            return Collections.emptyMap();
        }

        /**
         * 删除 item
         *
         * @param lid      location id
         * @param aid      area id
         * @param id       item id
         * @param property 资产标识
         * @return {}
         * @author yyt
         * @date 2023/5/12
         */
        @ApiId(300)
        @DeleteMapping("/location/{lid:\\d+}/area/{aid:\\d+}/item/{id:\\d+}")
        public Map deleteItem(@PathVariable int lid, @PathVariable int aid, @PathVariable int id, String property) {
            EngineeringRequestLocation location = engineeringRequestLocationService.checkExist(lid);

            Integer propertyId = sessionContext.getPropertyId(property);
            checkLocationPropertySame(location, propertyId);

            EngineeringRequestArea area = engineeringRequestAreaService.checkExist(lid, aid);
            checkAreaPropertySame(area, propertyId);
            checkAreaBelongLocation(area, location);

            EngineeringRequestItem item = engineeringRequestItemService.checkExist(lid, aid, id);
            checkItemPropertySame(item, propertyId);
            checkItemBelongArea(item, area);

            engineeringRequestService.checkItemUsed(propertyId, id);

            engineeringRequestItemService.delete(item);

            return Collections.emptyMap();
        }

        /**
         * 获取 issue 列表
         *
         * @param property 资产标识
         * @param query    搜索条件
         * @return issue 列表
         * @author yyt
         * @date 2023/5/12
         */
        @ApiId(301)
        @GetMapping("/issue")
        public ListPagedDTO<IssueDTO> listIssue(String property, SelectOptionQuery query) {
            Integer propertyId = sessionContext.getPropertyId(property);

            if (Objects.nonNull(query.getPage()) && Objects.nonNull(query.getSize())) {
                query.setPropertyId(propertyId);
                Page<EngineeringRequestIssue> page = engineeringRequestIssueService.page(query);
                return new ListPagedDTO<>(page.getTotal(), beanMapper.mapList(page.getRecords(), IssueDTO.class));
            } else {
                List<EngineeringRequestIssue> issues = engineeringRequestIssueService.listByCondition(propertyId, query);
                return new ListPagedDTO<>(issues.size(), beanMapper.mapList(issues, IssueDTO.class));
            }
        }

        /**
         * 新增 issue
         *
         * @param property 资产标识
         * @param issueDTO issue
         * @return {}
         * @author yyt
         * @date 2023/5/12
         */
        @ApiId(302)
        @PostMapping("/issue")
        public Map addIssue(String property, @Valid @RequestBody IssueDTO issueDTO) {
            Integer propertyId = sessionContext.getPropertyId(property);

            engineeringRequestIssueService.checkExist(propertyId, issueDTO.getName(), null);

            engineeringRequestIssueService.save(propertyId, issueDTO, sessionContext.getLoginUserId());

            return Collections.emptyMap();
        }

        /**
         * 编辑 issue
         *
         * @param id       location id
         * @param property 资产标识
         * @param issueDTO issue
         * @return {}
         * @author yyt
         * @date 2023/5/12
         */
        @ApiId(303)
        @PutMapping("/issue/{id:\\d+}")
        public Map updateIssue(@PathVariable int id, String property, @Valid @RequestBody IssueDTO issueDTO) {
            EngineeringRequestIssue issue = engineeringRequestIssueService.checkExist(id);

            Integer propertyId = sessionContext.getPropertyId(property);
            checkIssuePropertySame(issue, propertyId);

            engineeringRequestIssueService.checkExist(propertyId, issueDTO.getName(), id);

            engineeringRequestIssueService.update(id, issueDTO, sessionContext.getLoginUserId());

            return Collections.emptyMap();
        }

        /**
         * 删除 issue
         *
         * @param id       location id
         * @param property 资产标识
         * @return {}
         * @author yyt
         * @date 2023/5/12
         */
        @ApiId(304)
        @DeleteMapping("/issue/{id:\\d+}")
        public Map deleteIssue(@PathVariable int id, String property) {
            EngineeringRequestIssue issue = engineeringRequestIssueService.checkExist(id);

            int propertyId = sessionContext.getPropertyId(property);
            checkIssuePropertySame(issue, propertyId);

            engineeringRequestService.checkIssueUsed(propertyId, id);

            engineeringRequestIssueService.delete(issue);

            return Collections.emptyMap();
        }

        /**
         * 校验 Engineering Request Location Property 与 参数 Property 一致
         *
         * @param location    Engineering Request Location
         * @param paramPropertyId 参数 Property
         * @author yyt
         * @date 2023/5/12
         */
        private void checkLocationPropertySame(EngineeringRequestLocation location, Integer paramPropertyId) {
            if (!location.getPropertyId().equals(paramPropertyId)) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "the property id parameter is different from " +
                        "the property id of the engineeringRequestLocation;propertyId:" + paramPropertyId +
                        ",engineeringRequestLocationPropertyId:" + location.getPropertyId() +
                        ",engineeringRequestLocationId:" + location.getId());
            }
        }

        /**
         * 校验 Engineering Request Location Property 与 参数 Property 一致
         *
         * @param area    Engineering Request Location
         * @param paramPropertyId 参数 Property
         * @author yyt
         * @date 2023/5/12
         */
        private void checkAreaPropertySame(EngineeringRequestArea area, Integer paramPropertyId) {
            if (!area.getPropertyId().equals(paramPropertyId)) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "the property id parameter is different from " +
                        "the property id of the engineeringRequestArea;propertyId:" + paramPropertyId +
                        ",engineeringRequestAreaPropertyId:" + area.getPropertyId() + ",engineeringRequestAreaId:" + area.getId());
            }
        }

        /**
         * 校验 Engineering Request Area 属于 Engineering Request Location
         *
         * @param area    Engineering Request Area
         * @param location Engineering Request Location
         * @author yyt
         * @date 2023/5/12
         */
        private void checkAreaBelongLocation(EngineeringRequestArea area, EngineeringRequestLocation location) {
            if (!area.getLocationId().equals(location.getId())) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(),
                        "the engineeringRequestArea does not belong to the current engineeringRequestLocation;id:" + area.getId()
                                + ",areaLocationId:" + area.getLocationId() + ",currentLocationId:" + location.getId());
            }
        }

        /**
         * 校验 Engineering Request Item Property 与 参数 Property 一致
         *
         * @param item    Engineering Request Item
         * @param paramPropertyId 参数 Property
         * @author yyt
         * @date 2023/5/12
         */
        private void checkItemPropertySame(EngineeringRequestItem item, Integer paramPropertyId) {
            if (!item.getPropertyId().equals(paramPropertyId)) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "the property id parameter is different from " +
                        "the property id of the engineeringRequestItem;propertyId:" + paramPropertyId +
                        ",engineeringRequestItemPropertyId:" + item.getPropertyId() + ",engineeringRequestItemId:" + item.getId());
            }
        }

        /**
         * 校验 Engineering Request Item 属于 Engineering Request Area
         *
         * @param item Engineering Request Item
         * @param area Engineering Request Area
         * @author yyt
         * @date 2023/5/12
         */
        private void checkItemBelongArea(EngineeringRequestItem item, EngineeringRequestArea area) {
            if (!item.getAreaId().equals(area.getId())) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(),
                        "the engineeringRequestItem does not belong to the current engineeringRequestArea;id:" + item.getId()
                                + ",itemAreaId:" + item.getAreaId() + ",currentAreaId:" + area.getId());
            }
        }

        /**
         * 校验 Engineering Request Location Property 与 参数 Property 一致
         *
         * @param issue           Engineering Request Issue
         * @param paramPropertyId 参数 Property
         * @author yyt
         * @date 2023/5/12
         */
        private void checkIssuePropertySame(EngineeringRequestIssue issue, Integer paramPropertyId) {
            if (!issue.getPropertyId().equals(paramPropertyId)) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "the property id parameter is different from " +
                        "the property id of the engineeringRequestIssue;propertyId:" + paramPropertyId +
                        ",engineeringRequestIssuePropertyId:" + issue.getPropertyId() +
                        ",engineeringRequestIssueId:" + issue.getId());
            }
        }

    }