# ScheduleDepartmentController.java

    package cloud.wconnect.workperformance.controller.schedule;

    import cloud.wconnect.commonlib.annotation.ApiId;
    import cloud.wconnect.commonlib.component.SessionContext;
    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.CommonErrorI18nConstant;
    import cloud.wconnect.commonlib.cons.CommonFieldI18nConstant;
    import cloud.wconnect.commonlib.cons.DataPermissionConfigConstant;
    import cloud.wconnect.commonlib.exception.BadRequestException;
    import cloud.wconnect.commonlib.exception.ForbiddenException;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.pojo.dto.RoleDTO;
    import cloud.wconnect.commonlib.pojo.dto.UsergroupDTO;
    import cloud.wconnect.commonlib.pojo.dto.jsonview.Views;
    import cloud.wconnect.commonlib.redis.PropertyI18nRedisService;
    import cloud.wconnect.commonlib.service.RoleInternalService;
    import cloud.wconnect.commonlib.service.UserInternalService;
    import cloud.wconnect.commonlib.service.UsergroupInternalService;
    import cloud.wconnect.commonlib.util.I18nMessageUtils;
    import cloud.wconnect.commonlib.util.JsonUtils;
    import cloud.wconnect.workperformance.entity.schedule.ScheduleDepartment;
    import cloud.wconnect.workperformance.entity.schedule.ScheduleDepartmentPermissionConfig;
    import cloud.wconnect.workperformance.pojo.dto.schedule.*;
    import cloud.wconnect.workperformance.pojo.query.schedule.ScheduleDepartmentQuery;
    import cloud.wconnect.workperformance.pojo.query.schedule.ScheduleEmployeeQuery;
    import cloud.wconnect.workperformance.service.schedule.IScheduleDepartmentEmployeeService;
    import cloud.wconnect.workperformance.service.schedule.IScheduleDepartmentPermissionConfigService;
    import cloud.wconnect.workperformance.service.schedule.IScheduleDepartmentService;
    import com.fasterxml.jackson.annotation.JsonView;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.google.common.collect.Lists;
    import jakarta.validation.Valid;
    import org.apache.commons.lang3.StringUtils;
    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;

    /**
     * 控制层：Schedule Department
     *
     * @author yyt
     * 2023/6/30
     */
    @RestController
    @RequestMapping("/schedule/department")
    public class ScheduleDepartmentController {

        @Autowired
        private SessionContext sessionContext;
        @Autowired
        private UserInternalService userInternalService;
        @Autowired
        private RoleInternalService roleInternalService;
        @Autowired
        private UsergroupInternalService usergroupInternalService;
        @Autowired
        private IScheduleDepartmentService scheduleDepartmentService;
        @Autowired
        private IScheduleDepartmentEmployeeService scheduleDepartmentEmployeeService;
        @Autowired
        private IScheduleDepartmentPermissionConfigService scheduleDepartmentPermissionConfigService;
        @Autowired
        private PropertyI18nRedisService propertyI18nRedisService;
        @Autowired
        private ObjectMapper objectMapper;
        @Autowired
        private I18nMessageUtils i18nMessageUtils;

        /**
         * 获取部门列表
         *
         * @param property 资产标识
         * @return 部门列表
         * @author yyt
         * @date 2023/6/30
         */
        @ApiId(404)
        @JsonView(Views.DetailsView.class)
        @GetMapping
        public List<ScheduleDepartmentDTO> listDepartments(String property, ScheduleDepartmentQuery query) {
            int propertyId = sessionContext.getPropertyId(property);
            return scheduleDepartmentService.listDTO(propertyId, query);
        }

        /**
         * 新增、编辑部门
         *
         * @param id                  部门 id
         * @param property            资产标识
         * @param updateDepartmentDTO 部门信息
         * @return {}
         * @author yyt
         * @date 2023/7/1
         */
        @ApiId(405)
        @PostMapping("/{id:\\d+}")
        public Map<String, Object> saveDepartment(@PathVariable int id, String property, @Valid @RequestBody UpdateDepartmentDTO updateDepartmentDTO) {
            Integer propertyId = sessionContext.getPropertyId(property);
            int userId = sessionContext.getLoginUserId();
            if (id == 0) {
                scheduleDepartmentService.checkExist(propertyId, updateDepartmentDTO.getDepartmentCode(), updateDepartmentDTO.getName(), null);
                scheduleDepartmentService.save(propertyId, updateDepartmentDTO, userId);
            } else {
                if (StringUtils.isEmpty(updateDepartmentDTO.getDepartmentCode())) {
                    throw new BadRequestException(CommonErrorI18nConstant.CANNOT_EMPTY,
                            i18nMessageUtils.getErrorParamMapNotNeedTranslate("departmentCode"),
                            BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "the departmentCode must not be empty");
                }

                scheduleDepartmentService.checkExist(propertyId, updateDepartmentDTO.getDepartmentCode(), updateDepartmentDTO.getName(), id);

                ScheduleDepartment scheduleDepartment = scheduleDepartmentService.checkExist(id);
                checkPropertySame(scheduleDepartment, propertyId);

                scheduleDepartmentService.update(id, updateDepartmentDTO, userId);
            }

            return Collections.emptyMap();
        }

        /**
         * 新增部门权限配置
         *
         * @param id                  部门 id
         * @param property            资产标识
         * @param permissionConfigDTO 权限配置
         * @return {}
         * @author yyt
         * @date 2023/7/1
         */
        @ApiId(406)
        @PostMapping("/{id:\\d+}/permission-config")
        public Map<String, Object> saveDepartmentPermissionConfig(@PathVariable int id, String property,
                                                  @Valid @RequestBody UpdateDepartmentPermissionConfigDTO permissionConfigDTO) {
            Integer propertyId = sessionContext.getPropertyId(property);
            ScheduleDepartment scheduleDepartment = scheduleDepartmentService.checkExist(id);
            checkPropertySame(scheduleDepartment, propertyId);

            // 校验数据存在
            checkTargetExist(propertyId, permissionConfigDTO);

            scheduleDepartmentPermissionConfigService.savePermissionConfig(propertyId, id, permissionConfigDTO, sessionContext.getLoginUserId());

            return Collections.emptyMap();
        }

        /**
         * 校验数据存在
         *
         * @param propertyId          资产 id
         * @param permissionConfigDTO 配置信息
         * @author yyt
         * @date 2023/7/11
         */
        private void checkTargetExist(Integer propertyId, UpdateDepartmentPermissionConfigDTO permissionConfigDTO) {
            Integer tenantId = sessionContext.getTenantSymbolBO().getId();
            switch (permissionConfigDTO.getTargetType()) {
                case DataPermissionConfigConstant.IDENTITY_TYPE_ROLE:
                    List<RoleDTO> roles = roleInternalService.getRoles(tenantId, propertyId, Lists.newArrayList(permissionConfigDTO.getTargetId()));
                    if (roles.isEmpty()) {
                        throw new BadRequestException(CommonErrorI18nConstant.DATA_NOT_EXIST,
                                i18nMessageUtils.getErrorParamMapNeedTranslate(CommonFieldI18nConstant.ROLE),
                                BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "the role is not found;id:"
                                + permissionConfigDTO.getTargetId());
                    }
                    if (roles.get(0).getFunctionId() != DataPermissionConfigConstant.FUNCTION_ID_SCHEDULE) {
                        throw new BadRequestException(CommonErrorI18nConstant.DATA_PERMISSION_INVALID,
                                BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                                "select a role that does not belong to the current function;roleId:" + permissionConfigDTO.getTargetId());
                    }
                    break;
                case DataPermissionConfigConstant.IDENTITY_TYPE_USER_GROUP:
                    List<UsergroupDTO> usergroups = usergroupInternalService.getUsergroups(tenantId, propertyId, Lists.newArrayList(permissionConfigDTO.getTargetId()));
                    if (usergroups.isEmpty()) {
                        throw new BadRequestException(CommonErrorI18nConstant.DATA_NOT_EXIST,
                                i18nMessageUtils.getErrorParamMapNeedTranslate(CommonFieldI18nConstant.USER_GROUP),
                                BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "the userGroup is not found;id:"
                                + permissionConfigDTO.getTargetId());
                    }
                    List<Integer> roleIds = JsonUtils.convertStringToList(objectMapper, usergroups.get(0).getRoles(), Integer.class);
                    roles = roleInternalService.getRoles(tenantId, propertyId, roleIds);
                    if (roles.isEmpty()) {
                        throw new BadRequestException(CommonErrorI18nConstant.DATA_NOT_EXIST,
                                i18nMessageUtils.getErrorParamMapNeedTranslate(CommonFieldI18nConstant.ROLE),
                                BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                                "the role is not found;id:" + permissionConfigDTO.getTargetId());
                    }
                    if (roles.stream().noneMatch(item -> item.getFunctionId() == DataPermissionConfigConstant.FUNCTION_ID_SCHEDULE)) {
                        throw new BadRequestException(CommonErrorI18nConstant.DATA_PERMISSION_INVALID,
                                BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                                "select a userGroup that does not belong to the current function;roleId:" + permissionConfigDTO.getTargetId());
                    }
                    break;
                case DataPermissionConfigConstant.IDENTITY_TYPE_USER:
                    userInternalService.checkUserIdEffective(tenantId, propertyId, permissionConfigDTO.getTargetId());
                    break;
                default:
            }
        }

        /**
         * 删除部门权限配置
         *
         * @param id       部门 id
         * @param configId 权限配置 id
         * @param property 资产标识
         * @return {}
         * @author yyt
         * @date 2023/7/1
         */
        @ApiId(407)
        @DeleteMapping("/{id:\\d+}/permission-config/{configId:\\d+}")
        public Map<String, Object> deleteDepartmentPermissionConfig(@PathVariable int id, @PathVariable int configId, String property) {
            Integer propertyId = sessionContext.getPropertyId(property);
            ScheduleDepartment scheduleDepartment = scheduleDepartmentService.checkExist(id);
            checkPropertySame(scheduleDepartment, propertyId);

            ScheduleDepartmentPermissionConfig config = scheduleDepartmentPermissionConfigService.checkExist(configId, id);
            checkPropertySame(config, propertyId);

            scheduleDepartmentPermissionConfigService.delete(configId);

            return Collections.emptyMap();
        }

        /**
         * 允许用户申请的部门权限
         *
         * @param id       部门 id
         * @param configId 权限配置 id
         * @param property 资产标识
         * @return {}
         * @author yyt
         * @date 2023/7/3
         */
        @ApiId(408)
        @PutMapping("/{id:\\d+}/permission-config/{configId:\\d+}/pass")
        public Map<String, Object> passPermissionConfig(@PathVariable int id, @PathVariable int configId, String property){
            int propertyId = sessionContext.getPropertyId(property);
            PropertyDTO propertyDTO = propertyI18nRedisService.get(propertyId);
            ScheduleDepartment scheduleDepartment = scheduleDepartmentService.checkExist(id);
            checkPropertySame(scheduleDepartment, propertyId);

            ScheduleDepartmentPermissionConfig config = scheduleDepartmentPermissionConfigService.checkExist(configId, id);
            checkPropertySame(config, propertyId);

            scheduleDepartmentPermissionConfigService.passPermissionConfig(config, propertyDTO);

            return Collections.emptyMap();
        }

        /**
         * 获取部门下员工列表
         *
         * @param id            部门 id
         * @param property      资产标识
         * @param employeeQuery 搜索条件
         * @return 员工
         * @author yyt
         * @date 2023/7/3
         */
        @JsonView(Views.OptionView.class)
        @ApiId(409)
        @GetMapping("/{id:\\d+}/employee")
        public List<ScheduleDepartmentEmployeeDTO> listEmployee(@PathVariable int id, String property, ScheduleEmployeeQuery employeeQuery) {
            Integer propertyId = sessionContext.getPropertyId(property);
            ScheduleDepartment scheduleDepartment = scheduleDepartmentService.checkExist(id);
            checkPropertySame(scheduleDepartment, propertyId);
            return scheduleDepartmentEmployeeService.listEmployee(propertyId, id, employeeQuery);
        }

        /**
         * 新增、编辑员工
         *
         * @param departmentId      部门 id
         * @param employeeId        员工 id
         * @param property          资产标识
         * @param updateEmployeeDTO 员工信息
         * @return {}
         * @author yyt
         * @date 2023/7/3
         */
        @ApiId(410)
        @PostMapping("/{departmentId:\\d+}/employee/{employeeId:\\d+}")
        public Map<String, Object> saveEmployee(@PathVariable int departmentId, @PathVariable int employeeId, String property,
                                @Valid @RequestBody UpdateEmployeeDTO updateEmployeeDTO) {
            Integer propertyId = sessionContext.getPropertyId(property);
            ScheduleDepartment scheduleDepartment = scheduleDepartmentService.checkExist(departmentId);
            checkPropertySame(scheduleDepartment, propertyId);

            int userId = sessionContext.getLoginUserId();

            if (employeeId == 0) {
                scheduleDepartmentEmployeeService.checkExist(propertyId, updateEmployeeDTO.getName(), null);

                scheduleDepartmentEmployeeService.save(propertyId, departmentId, updateEmployeeDTO, userId);
            } else {
                scheduleDepartmentEmployeeService.checkExist(propertyId, updateEmployeeDTO.getName(), employeeId);

                scheduleDepartmentEmployeeService.update(employeeId, updateEmployeeDTO, userId);
            }

            return Collections.emptyMap();
        }

        /**
         * 异步刷新权限配置状态
         *
         * @param property 资产标识
         * @return {}
         * @author yyt
         * @date 2023/7/3
         */
        @ApiId(411)
        @PutMapping("/permission-config/flush/status")
        public Map<String, Object> flushPermissionConfigStatus(String property){
            scheduleDepartmentPermissionConfigService.flushPermissionConfigStatus(sessionContext.getPropertyId(property));
            return Collections.emptyMap();
        }

        /**
         * 校验 scheduleDepartment property 与 参数 property 一致
         *
         * @param scheduleDepartment scheduleDepartment
         * @param propertyId         参数 property
         * @author yyt
         * @date 2023/7/1
         */
        private void checkPropertySame(ScheduleDepartment scheduleDepartment, Integer propertyId) {
            if (!scheduleDepartment.getPropertyId().equals(propertyId)) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "the property id parameter is different from " +
                        "the property id of the scheduleDepartment;propertyId:" + propertyId + ",scheduleDepartmentPropertyId:" +
                        scheduleDepartment.getPropertyId() + ",scheduleDepartmentId:" + scheduleDepartment.getId());
            }
        }

        /**
         * 校验 scheduleDepartmentPermissionConfig property 与 参数 property 一致
         *
         * @param config scheduleDepartmentPermissionConfig
         * @param propertyId         参数 property
         * @author yyt
         * @date 2023/7/1
         */
        private void checkPropertySame(ScheduleDepartmentPermissionConfig config, Integer propertyId) {
            if (!config.getPropertyId().equals(propertyId)) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "the property id parameter is different from " +
                        "the property id of the scheduleDepartmentPermissionConfig;propertyId:" + propertyId +
                        ",scheduleDepartmentPermissionConfigPropertyId:" + config.getPropertyId() +
                        ",scheduleDepartmentPermissionConfigId:" + config.getId());
            }
        }

    }