package com.wms.controller;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wms.annotation.MyLog;
import com.wms.constants.WmsConstants;
import com.wms.constants.enums.ResponseCode;
import com.wms.entity.app.ResponseEntity;
import com.wms.entity.app.dto.KateUser;
import com.wms.entity.app.dto.MenuDto;
import com.wms.entity.app.dto.PageDto;
import com.wms.entity.app.dto.UserDto;
import com.wms.entity.app.request.*;
import com.wms.entity.app.vo.*;
import com.wms.entity.table.Menu;
import com.wms.entity.table.Permission;
import com.wms.entity.table.Role;
import com.wms.entity.table.User;
import com.wms.service.*;
import com.wms.utils.HttpUtils;
import com.wms.utils.MyPassword;
import com.wms.utils.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

import static com.wms.utils.StringUtils.convertJsonString;

/**
 * WMS用户控制类
 *
 * @author 梁州
 * &#064;date  2023/2/14
 */
@Controller
@CrossOrigin
@RequestMapping(value = "/wms/user")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class UserController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * 请求头部信息
     */
    private final HttpServletRequest servletRequest;
    /**
     * 用户服务
     */
    private final UserService userService;
    /**
     * 菜单服务
     */
    private final MenuService menuService;
    /**
     * 站台服务
     */
    private final StandService standService;
    /**
     * 角色服务
     */
    private final RoleService roleService;
    /**
     * 权限服务
     */
    private final PermissionService permissionService;

    /**
     * 带密码登录
     *
     * @param userQuery 用户
     * @return 结果
     */
    @PostMapping("/loginWithAuth")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "带密码登录", logMethod = "loginWithAuth")
    public String loginWithAuth(@RequestBody UserQuery userQuery) {
        logger.info("请求登录，登录账户名：{}，登录ip：{}", userQuery.getLoginAccount(), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (StringUtils.isEmpty(userQuery.getLoginAccount())) {
                logger.error("请输入用户名");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("请输入用户名");
                return convertJsonString(rsp);
            }
            // 验证用户信息
            UserDto validatedUser = userService.validateUser(userQuery.toUserPO(), true);
            if (validatedUser == null || StringUtils.isEmpty(validatedUser.getLoginAccount())) {
                logger.error("登录错误，用户不存在或密码错误");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("登录错误，用户不存在或密码错误");
                return convertJsonString(rsp);
            }

            // 返回成功
            logger.info("登录成功，登录账户名：{}", validatedUser.getLoginAccount());
            rsp.setCode(ResponseCode.OK.getCode());
            rsp.setMessage("登录成功");
            // 返回用户数据
            rsp.setReturnData(generateUserInfo(validatedUser, HttpUtils.getIpAddr(servletRequest)));
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.info("数据库错误：{}", convertJsonString(e));
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("登录异常");
            return convertJsonString(rsp);
        }
    }

    /**
     * 无密码登录
     *
     * @param userQuery 用户
     * @return 结果
     */
    @PostMapping("/loginWithoutAuth")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "无密码登录", logMethod = "loginWithoutAuth")
    public String loginWithoutAuth(@RequestBody UserQuery userQuery) {
        logger.info("请求无密码登录，登录账户名：{}，登录ip：{}", userQuery.getLoginAccount(), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (StringUtils.isEmpty(userQuery.getLoginAccount())) {
                logger.error("请输入用户名");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("请输入用户名");
                return convertJsonString(rsp);
            }
            // 验证用户信息
            UserDto validatedUser = userService.validateUser(userQuery.toUserPO(), false);
            if (validatedUser == null || StringUtils.isEmpty(validatedUser.getLoginAccount())) {
                logger.error("登录错误，用户不存在或密码错误");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("登录错误，用户不存在或密码错误");
                return convertJsonString(rsp);
            }

            // 返回成功
            logger.info("登录成功，登录账户名：{}", validatedUser.getLoginAccount());
            rsp.setCode(ResponseCode.OK.getCode());
            rsp.setMessage("登录成功");
            // 返回用户数据
            rsp.setReturnData(generateUserInfo(validatedUser, HttpUtils.getIpAddr(servletRequest)));
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.info("数据库错误：{}", convertJsonString(e));
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("登录异常");
            return convertJsonString(rsp);
        }
    }

    /**
     * 获得用户信息菜单
     *
     * @param codeInfo code信息
     * @return 结果
     */
    @PostMapping("/getUser")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "获得用户信息菜单", logMethod = "getUser")
    public String getUser(@RequestBody JSONObject codeInfo) {
        logger.info("卡特账号请求登录，登录信息：{}，登录ip：{}", convertJsonString(codeInfo), HttpUtils.getIpAddr(servletRequest));
        // 响应信息
        ResponseEntity rsp = new ResponseEntity();
        String idToken = codeInfo.getString("id_token");
        logger.info("卡特登录回调，idToken：{}", idToken);
        if (StringUtils.isEmpty(idToken)) {
            logger.error("ID_TOKEN为空");
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("ID_TOKEN为空");
            return JSON.toJSONString(rsp);
        }
        try {
            // 解码token
            DecodedJWT decodedJWT = JWT.decode(idToken);
            // 创建用户信息
            KateUser kateUser = new KateUser();
            kateUser.setName(decodedJWT.getClaim("name").asString());
            kateUser.setGroups(decodedJWT.getClaim("groups").asList(String.class));
            // 卡特用户信息映射本地用户信息
            User newUser = new User();
            newUser.setUserName(kateUser.getName());
            List<User> localUsers = userService.list(new LambdaQueryWrapper<User>()
                    .eq(User::getUserName, kateUser.getName()));
            if (!localUsers.isEmpty()) {// 本地存在
                newUser.setRoleId(localUsers.get(0).getRoleId());
            } else {
                if (kateUser.getGroups().contains("CXL-ASRS-Admin")) {// 普通用户
                    newUser.setRoleId(1);
                } else if (kateUser.getGroups().contains("CXL-ASRS-User")) {
                    newUser.setRoleId(2);
                } else {
                    logger.error("当前用户不被允许登录：{}", newUser.getUserName());
                    rsp.setCode(ResponseCode.ERROR.getCode());
                    rsp.setMessage("当前用户不被允许登录");
                    return JSON.toJSONString(rsp);
                }
            }
            // 返回成功
            logger.info("登录成功，登录用户：{}", newUser.getUserName());
            rsp.setCode(ResponseCode.OK.getCode());
            rsp.setMessage("登录成功");
            // 返回用户数据
            rsp.setReturnData(generateUserInfo(BeanUtil.copyProperties(newUser, UserDto.class), HttpUtils.getIpAddr(servletRequest)));
        } catch (Exception exception) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error(exception.getMessage());
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("构建用户及菜单错误");
        }
        return JSON.toJSONString(rsp);
    }

    /**
     * 构造用户信息（菜单、按钮等权限）
     *
     * @param currentUser 当前用户
     * @param ip          ip地址
     * @return 用户信息
     */
    private UserConfigEntity generateUserInfo(UserDto currentUser, String ip) {
        UserConfigEntity userConfigEntity = new UserConfigEntity();
        try {
            if (currentUser.getRoleId() == null) {
                return null;
            }
            List<MenuDto> menus = menuService.selMenuByRoleId(currentUser.getRoleId());
            List<MenuEntity> menuList = new LinkedList<>();
            // 查找一级菜单
            for (MenuDto firstMenu : menus) {
                if (WmsConstants.ROOT_MENU_ID.equals(firstMenu.getParentId())) {// 查找到所有的一级子菜单
                    MenuEntity tempFirstMenu = new MenuEntity();
                    tempFirstMenu.setId(firstMenu.getMenuId());// ID
                    tempFirstMenu.setLabelName(firstMenu.getLabelName());// 菜单显示名称
                    tempFirstMenu.setIconValue(firstMenu.getIconValue());// 图标
                    tempFirstMenu.setPath(firstMenu.getPath());// 路径
                    // 设置子菜单
                    List<MenuEntity> tempFirstMenuChildren = new LinkedList<>();
                    for (MenuDto secondMenu : menus) {
                        if (firstMenu.getMenuId().equals(secondMenu.getParentId())) {
                            MenuEntity tempSecondMenu = new MenuEntity();
                            tempSecondMenu.setId(secondMenu.getMenuId());// ID
                            tempSecondMenu.setLabelName(secondMenu.getLabelName());// 菜单显示名称
                            tempSecondMenu.setIconValue(secondMenu.getIconValue());// 图标
                            tempSecondMenu.setPath(secondMenu.getPath());// 路径
                            // 设置子菜单
                            List<MenuEntity> tempSecondMenuChildren = new LinkedList<>();
                            for (MenuDto thirdMenu : menus) {
                                if (secondMenu.getMenuId().equals(thirdMenu.getParentId())) {
                                    MenuEntity tempThirdMenu = new MenuEntity();
                                    tempSecondMenu.setId(thirdMenu.getMenuId());// ID
                                    tempSecondMenu.setLabelName(thirdMenu.getLabelName());// 菜单显示名称
                                    tempSecondMenu.setIconValue(thirdMenu.getIconValue());// 图标
                                    tempSecondMenu.setPath(thirdMenu.getPath());// 路径
                                    // 添加按钮
                                    tempSecondMenuChildren.add(tempThirdMenu);
                                }
                            }
                            tempSecondMenu.setChildren(tempSecondMenuChildren);
                            // 添加二级菜单
                            tempFirstMenuChildren.add(tempSecondMenu);
                        }
                    }
                    tempFirstMenu.setChildren(tempFirstMenuChildren);
                    // 添加一级菜单
                    menuList.add(tempFirstMenu);
                }
            }
            logger.info("构造用户信息成功，当前用户：{}", currentUser.getUserName());
            // 设置返回信息
            userConfigEntity.setUser(BeanUtil.copyProperties(currentUser, UserDto.class));
            userConfigEntity.setMenuList(menuList);
            userConfigEntity.setStandId(standService.getStandIdByIp(ip));
        } catch (Exception e) {
            logger.error("构造用户信息失败，当前用户：{}", currentUser.getUserName());
        }
        return userConfigEntity;
    }

    /**
     * 获取用户列表
     *
     * @param userQuery 查询参数
     * @return 结果
     */
    @PostMapping("/getUserList")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "获取用户列表", logMethod = "getUserList")
    public String getUserList(@RequestBody UserQuery userQuery) {
        logger.info("获取用户列表，请求用户名：{}，登录ip：{}", userQuery.getUserName(), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (userQuery.getRoleId() == null || userQuery.getRoleId() != 1) {
                logger.error("操作人员必须是管理员级别。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("操作人员必须是管理员级别。");
                return convertJsonString(rsp);
            }
            // 查询roleId低于当前查询的roleId的用户
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>()
                    .ge(User::getRoleId, userQuery.getRoleId())
                    .orderByAsc(User::getRoleId, User::getUserId);
            if (StringUtils.isNotEmpty(userQuery.getUserName())) {
                queryWrapper.like(User::getUserName, userQuery.getUserName());
            }
            Page<User> page = userQuery.toMpPage();
            Page<User> userPage = userService.page(page, queryWrapper);
            PageDto<UserVo> pageDto = PageDto.of(userPage, UserVo::of);
            // 返回成功
            logger.info("查询用户列表成功。");
            rsp.setCode(ResponseCode.OK.getCode());
            rsp.setMessage("查询用户列表成功。");
            // 返回用户数据
            rsp.setReturnData(pageDto);
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.info("查询用户列表失败：{}", convertJsonString(e));
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("查询用户列表失败。");
            return convertJsonString(rsp);
        }
    }

    /**
     * 获取角色列表
     *
     * @param roleQuery 查询参数
     * @return 结果
     */
    @PostMapping("/getRoleList")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "获取角色列表", logMethod = "getRoleList")
    public String getRoleList(@RequestBody RoleQuery roleQuery) {
        logger.info("获取角色列表，请求用户名：{}，登录ip：{}", roleQuery.getUserName(), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (roleQuery.getRoleId() == null || roleQuery.getRoleId() != 1) {
                logger.error("操作人员必须是管理员级别。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("操作人员必须是管理员级别。");
                return convertJsonString(rsp);
            }
            // 查询roleId低于当前查询的roleId的用户
            LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<Role>()
                    .ge(Role::getRoleId, roleQuery.getRoleId())
                    .orderByAsc(Role::getRoleId);
            Page<Role> page = roleQuery.toMpPage();
            Page<Role> rolePage = roleService.page(page, queryWrapper);
            PageDto<RoleVo> pageDto = PageDto.of(rolePage, RoleVo::of);
            // 返回成功
            logger.info("查询角色列表成功。");
            rsp.setCode(ResponseCode.OK.getCode());
            rsp.setMessage("查询角色列表成功。");
            // 返回用户数据
            rsp.setReturnData(pageDto);
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.info("查询角色列表失败：{}", convertJsonString(e));
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("查询角色列表失败。");
            return convertJsonString(rsp);
        }
    }

    /**
     * 获取角色options
     *
     * @param roleQuery 查询参数
     * @return 结果
     */
    @PostMapping("/getRoleOptions")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "获取角色options", logMethod = "getRoleOptions")
    public String getRoleOptions(@RequestBody RoleQuery roleQuery) {
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (roleQuery.getRoleId() == null || roleQuery.getRoleId() != 1) {
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("操作人员必须是管理员级别。");
                return convertJsonString(rsp);
            }
            // 查询roleId低于当前查询的roleId的用户
            LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<Role>()
                    .ge(Role::getRoleId, roleQuery.getRoleId())
                    .orderByAsc(Role::getRoleId);
            List<Role> roleList = roleService.list(queryWrapper);
            List<RoleOption> roleOptions = roleList.stream().map(RoleOption::of).toList();
            // 返回成功
            rsp.setCode(ResponseCode.OK.getCode());
            rsp.setMessage("查询角色列表成功。");
            // 返回用户数据
            rsp.setReturnData(roleOptions);
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.info("获取角色options失败：{}", convertJsonString(e));
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("获取角色options。");
            return convertJsonString(rsp);
        }
    }

    /**
     * 获取权限列表
     *
     * @param permissionQuery 查询参数
     * @return 结果
     */
    @PostMapping("/getPermissionList")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "获取权限列表", logMethod = "getPermissionList")
    public String getPermissionList(@RequestBody PermissionQuery permissionQuery) {
        logger.info("获取权限列表，请求用户名：{}，登录ip：{}", permissionQuery.getUserName(), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (permissionQuery.getRoleId1() == null || permissionQuery.getRoleId1() != 1) {
                logger.error("操作人员必须是管理员级别。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("操作人员必须是管理员级别。");
                return convertJsonString(rsp);
            }
            // 获取所有的菜单信息
            List<Permission> permissionList = permissionService.list(
                    new LambdaQueryWrapper<Permission>().eq(Permission::getRoleId, permissionQuery.getRoleId1()).orderByAsc(Permission::getMenuId)
            );
            if (permissionList == null || permissionList.isEmpty()) {
                logger.error("操作人员的角色没有权限。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("操作人员的角色没有权限。");
                return convertJsonString(rsp);
            }
            List<String> menuIds = permissionList.stream().map(Permission::getMenuId).distinct().toList();
            // 查询所有的菜单
            List<Menu> menuList = menuService.list(
                    new LambdaQueryWrapper<Menu>().in(Menu::getMenuId, menuIds).orderByAsc(Menu::getMenuId)
            );
            // 先添加一级菜单
            List<MenuVo> level1Menus = menuList.stream().filter(menu -> Objects.equals(menu.getParentId(), WmsConstants.ROOT_MENU_ID)).map(MenuVo::of).toList();
            // 添加二级菜单
            for (MenuVo level1Menu : level1Menus) {
                level1Menu.setChildren(menuList.stream().filter(menu -> Objects.equals(menu.getParentId(), level1Menu.getId())).map(MenuVo::of).toList());
            }
            PermissionVo permissionVo = new PermissionVo();
            permissionVo.setMenu(level1Menus);
            // 获取待查询角色所有菜单权限
            if (permissionQuery.getRoleId2() != null) {
                List<Permission> permissionListOfTarget = permissionService.list(
                        new LambdaQueryWrapper<Permission>()
                                .eq(Permission::getRoleId, permissionQuery.getRoleId2())
                                .notIn(Permission::getMenuId, level1Menus.stream().map(MenuVo::getId).distinct().toList())
                                .orderByAsc(Permission::getMenuId)
                );
                permissionVo.setMenuIds(permissionListOfTarget.stream().map(Permission::getMenuId).distinct().toList());
            } else {
                permissionVo.setMenuIds(new ArrayList<>());
            }

            logger.info("查询权限列表成功。");
            rsp.setCode(ResponseCode.OK.getCode());
            rsp.setMessage("查询权限列表成功。");
            // 返回用户数据
            rsp.setReturnData(permissionVo);
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            // 返回其他异常
            logger.error("查询权限列表异常：{}", convertJsonString(e));
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("查询权限列表异常。");
            return convertJsonString(rsp);
        }
    }

    /**
     * 更新角色信息
     *
     * @param roleUpdateForm 更新参数
     * @return 结果
     */
    @PostMapping("/updateRoleInfo")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "更新角色信息", logMethod = "updateRoleInfo")
    public String updateRoleInfo(@RequestBody RoleUpdateForm roleUpdateForm) {
        logger.info("更新角色信息，请求用户名：{}，登录ip：{}", roleUpdateForm.getUserName(), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (roleUpdateForm.getRoleId1() == null || roleUpdateForm.getRoleId2() == null) {
                logger.error("请求操作的roleId和被操作的roleId必须输入。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("请求操作的roleId和被操作的roleId必须输入。");
                return convertJsonString(rsp);
            }
            if (roleUpdateForm.getRoleId1() != 1) {
                logger.error("操作人员必须是管理员级别。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("操作人员必须是管理员级别。");
                return convertJsonString(rsp);
            }
            // 更新角色信息
            if (StringUtils.isNotEmpty(roleUpdateForm.getRole2Name())) {
                roleService.update(new LambdaUpdateWrapper<Role>().set(Role::getRoleName, roleUpdateForm.getRole2Name()).eq(Role::getRoleId, roleUpdateForm.getRoleId2()));
            }
            // 获取所有的菜单信息
            List<Permission> permissionList = permissionService.list(
                    new LambdaQueryWrapper<Permission>().eq(Permission::getRoleId, roleUpdateForm.getRoleId1()).orderByAsc(Permission::getMenuId)
            );
            if (permissionList == null || permissionList.isEmpty()) {
                logger.error("操作人员的角色没有权限。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("操作人员的角色没有权限。");
                return convertJsonString(rsp);
            }
            List<String> menuIds = permissionList.stream().map(Permission::getMenuId).distinct().toList();
            List<String> updateMenuIds = roleUpdateForm.getMenuIds();
            for (String menuId : updateMenuIds) {
                if (!menuIds.contains(menuId)) {
                    logger.error("设定的权限超过操作人员所拥有的权限。");
                    // 返回错误
                    rsp.setCode(ResponseCode.ERROR.getCode());
                    rsp.setMessage("设定的权限超过操作人员所拥有的权限。");
                    return convertJsonString(rsp);
                }
            }
            // 查询所有的菜单
            List<Menu> menuList = menuService.list(
                    new LambdaQueryWrapper<Menu>().in(Menu::getMenuId, updateMenuIds).orderByAsc(Menu::getMenuId)
            );
            for (Menu menu : menuList) {
                if (menu.getParentId() != null && !menu.getParentId().equals(WmsConstants.ROOT_MENU_ID) && !updateMenuIds.contains(menu.getParentId())) {
                    updateMenuIds.add(menu.getParentId());
                }
            }
            // 移除角色所有权限
            permissionService.remove(new LambdaQueryWrapper<Permission>().eq(Permission::getRoleId, roleUpdateForm.getRoleId2()));
            // 添加权限
            List<Permission> updatePermissionList = new ArrayList<>();
            for (String menuId : updateMenuIds) {
                // 添加权限
                Permission permission = new Permission();
                permission.setRoleId(roleUpdateForm.getRoleId2());
                permission.setMenuId(menuId);
                updatePermissionList.add(permission);
            }
            if (permissionService.saveBatch(updatePermissionList)) {
                // 返回成功
                logger.info("更新角色信息成功。");
                rsp.setCode(ResponseCode.OK.getCode());
                rsp.setMessage("更新角色信息成功。");
            } else {
                // 返回失败
                logger.error("更新角色权限失败。");
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("更新角色权限失败。");
            }
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.info("更新角色信息失败：{}", convertJsonString(e));
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("更新角色信息失败。");
            return convertJsonString(rsp);
        }
    }

    /**
     * 添加角色信息
     *
     * @param roleUpdateForm 添加参数
     * @return 结果
     */
    @PostMapping("/addRoleInfo")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "添加角色信息", logMethod = "addRoleInfo")
    public String addRoleInfo(@RequestBody RoleUpdateForm roleUpdateForm) {
        logger.info("添加角色信息，请求用户名：{}，登录ip：{}", roleUpdateForm.getUserName(), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (roleUpdateForm.getRoleId1() == null || roleUpdateForm.getRoleId1() != 1) {
                logger.error("操作人员必须是管理员级别。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("操作人员必须是管理员级别。");
                return convertJsonString(rsp);
            }
            // 添加角色信息
            Role role = new Role();
            role.setRoleId(roleService.getOne(new LambdaQueryWrapper<Role>().select(Role::getRoleId).orderByDesc(Role::getRoleId).last("limit 1")).getRoleId() + 1);
            role.setRoleName(roleUpdateForm.getRole2Name());
            if (!roleService.save(role)) {
                // 添加失败
                logger.error("添加角色信息失败。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("添加角色信息失败。");
                return convertJsonString(rsp);
            }
            // 获取所有的菜单信息
            List<Permission> permissionList = permissionService.list(
                    new LambdaQueryWrapper<Permission>().eq(Permission::getRoleId, roleUpdateForm.getRoleId1()).orderByAsc(Permission::getMenuId)
            );
            if (permissionList == null || permissionList.isEmpty()) {
                logger.error("操作人员的角色没有权限。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("操作人员的角色没有权限。");
                return convertJsonString(rsp);
            }
            List<String> menuIds = permissionList.stream().map(Permission::getMenuId).distinct().toList();
            List<String> updateMenuIds = roleUpdateForm.getMenuIds();
            for (String menuId : updateMenuIds) {
                if (!menuIds.contains(menuId)) {
                    logger.error("设定的权限超过操作人员所拥有的权限。");
                    // 返回错误
                    rsp.setCode(ResponseCode.ERROR.getCode());
                    rsp.setMessage("设定的权限超过操作人员所拥有的权限。");
                    return convertJsonString(rsp);
                }
            }
            // 查询所有的菜单
            List<Menu> menuList = menuService.list(
                    new LambdaQueryWrapper<Menu>().in(Menu::getMenuId, updateMenuIds).orderByAsc(Menu::getMenuId)
            );
            for (Menu menu : menuList) {
                if (menu.getParentId() != null && !menu.getParentId().equals(WmsConstants.ROOT_MENU_ID) && !updateMenuIds.contains(menu.getParentId())) {
                    updateMenuIds.add(menu.getParentId());
                }
            }
            // 移除角色所有权限
            permissionService.remove(new LambdaQueryWrapper<Permission>().eq(Permission::getRoleId, role.getRoleId()));
            // 添加权限
            List<Permission> updatePermissionList = new ArrayList<>();
            for (String menuId : updateMenuIds) {
                // 添加权限
                Permission permission = new Permission();
                permission.setRoleId(role.getRoleId());
                permission.setMenuId(menuId);
                updatePermissionList.add(permission);
            }
            if (permissionService.saveBatch(updatePermissionList)) {
                // 返回成功
                logger.info("添加角色信息成功。");
                rsp.setCode(ResponseCode.OK.getCode());
                rsp.setMessage("添加角色信息成功。");
            } else {
                // 返回失败
                logger.error("添加角色权限失败。");
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("添加角色权限失败。");
            }
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.info("添加角色信息失败：{}", convertJsonString(e));
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("添加角色信息失败。");
            return convertJsonString(rsp);
        }
    }

    /**
     * 删除角色信息
     *
     * @param roleUpdateForm 更新参数
     * @return 结果
     */
    @PostMapping("/deleteRoleInfo")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "删除角色信息", logMethod = "deleteRoleInfo")
    public String deleteRoleInfo(@RequestBody RoleUpdateForm roleUpdateForm) {
        logger.info("删除角色信息，请求用户名：{}，登录ip：{}", roleUpdateForm.getUserName(), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (roleUpdateForm.getRoleId1() == null || roleUpdateForm.getRoleId2() == null) {
                logger.error("请求操作的roleId和被操作的roleId必须输入。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("请求操作的roleId和被操作的roleId必须输入。");
                return convertJsonString(rsp);
            }
            if (roleUpdateForm.getRoleId1() != 1) {
                logger.error("操作人员必须是管理员级别。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("操作人员必须是管理员级别。");
                return convertJsonString(rsp);
            }
            // 删除角色信息
            roleService.remove(new LambdaQueryWrapper<Role>().eq(Role::getRoleId, roleUpdateForm.getRoleId2()));
            // 移除角色所有权限
            permissionService.remove(new LambdaQueryWrapper<Permission>().eq(Permission::getRoleId, roleUpdateForm.getRoleId2()));
            // 返回成功
            logger.info("删除角色信息成功。");
            rsp.setCode(ResponseCode.OK.getCode());
            rsp.setMessage("删除角色信息成功。");
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.info("删除角色信息失败：{}", convertJsonString(e));
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("删除角色信息失败。");
            return convertJsonString(rsp);
        }
    }

    /**
     * 更新用户信息
     *
     * @param userUpdateForm 更新参数
     * @return 结果
     */
    @PostMapping("/updateUserInfo")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "更新用户信息", logMethod = "updateUserInfo")
    public String updateUserInfo(@RequestBody UserUpdateForm userUpdateForm) {
        logger.info("更新用户信息，请求用户名：{}，登录ip：{}", userUpdateForm.getUserName(), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (userUpdateForm.getRoleId1() == null || userUpdateForm.getRoleId1() != 1) {
                logger.error("操作人员必须是管理员级别。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("操作人员必须是管理员级别。");
                return convertJsonString(rsp);
            }
            if (userUpdateForm.getUserIdUpdate() == null) {
                logger.error("缺少用户id。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("缺少用户id。");
                return convertJsonString(rsp);
            }
            // 更新用户信息
            User updateUser = userService.getById(userUpdateForm.getUserIdUpdate());
            if (updateUser == null) {
                logger.error("用户不存在。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("用户不存在。");
                return convertJsonString(rsp);
            }
            if (StringUtils.isNotEmpty(userUpdateForm.getUserNameUpdate())) {
                updateUser.setUserName(userUpdateForm.getUserNameUpdate());
            }
            if (StringUtils.isNotEmpty(userUpdateForm.getLoginAccountUpdate())) {
                updateUser.setLoginAccount(userUpdateForm.getLoginAccountUpdate());
            }
            if (userUpdateForm.getRoleIdUpdate() != null) {
                updateUser.setRoleId(userUpdateForm.getRoleIdUpdate());
            }
            updateUser.setUpdateTime(LocalDateTime.now());
            if (userService.updateById(updateUser)) {
                logger.info("更新用户信息成功。");
                rsp.setCode(ResponseCode.OK.getCode());
                rsp.setMessage("更新用户信息成功。");
            } else {
                logger.error("更新用户信息失败。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("更新用户信息失败。");
            }
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.info("更新用户信息失败：{}", convertJsonString(e));
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("更新用户信息失败。");
            return convertJsonString(rsp);
        }
    }

    /**
     * 添加用户信息
     *
     * @param userUpdateForm 添加参数
     * @return 结果
     */
    @PostMapping("/addUserInfo")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "添加用户信息", logMethod = "addUserInfo")
    public String addUserInfo(@RequestBody UserUpdateForm userUpdateForm) {
        logger.info("添加用户信息，请求用户名：{}，登录ip：{}", userUpdateForm.getUserName(), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (userUpdateForm.getRoleId1() == null || userUpdateForm.getRoleId1() != 1) {
                logger.error("操作人员必须是管理员级别。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("操作人员必须是管理员级别。");
                return convertJsonString(rsp);
            }
            if (StringUtils.isEmpty(userUpdateForm.getUserNameUpdate())) {
                logger.error("请输入用户名。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("请输入用户名。");
                return convertJsonString(rsp);
            }
            if (StringUtils.isEmpty(userUpdateForm.getLoginAccountUpdate())) {
                logger.error("请输入登录账号。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("请输入登录账号。");
                return convertJsonString(rsp);
            }
            if (userUpdateForm.getRoleIdUpdate() == null) {
                logger.error("请选择角色。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("请选择角色。");
                return convertJsonString(rsp);
            }
            // 判断loginAccount是否重复
            if (userService.exists(new LambdaQueryWrapper<User>().eq(User::getLoginAccount, userUpdateForm.getLoginAccountUpdate()))) {
                logger.error("登录账号重复。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("登录账号重复。");
                return convertJsonString(rsp);
            }
            // 添加角色信息
            User newUser = new User();
            newUser.setUserId(userService.getOne(new LambdaQueryWrapper<User>().select(User::getUserId).orderByDesc(User::getUserId).last("limit 1")).getUserId() + 1);
            newUser.setUserName(userUpdateForm.getUserNameUpdate());
            newUser.setLoginAccount(userUpdateForm.getLoginAccountUpdate());
            if (StringUtils.isEmpty(userUpdateForm.getLoginPasswordUpdate())) {
                newUser.setLoginPassword("");
            } else {
                newUser.setLoginPassword(MyPassword.encrypt(userUpdateForm.getLoginPasswordUpdate()));
            }
            newUser.setRoleId(userUpdateForm.getRoleIdUpdate());
            newUser.setAddTime(LocalDateTime.now());
            newUser.setUpdateTime(LocalDateTime.now());
            newUser.setAddUser(userUpdateForm.getUserName());
            if (userService.save(newUser)) {
                logger.info("添加用户信息成功。");
                rsp.setCode(ResponseCode.OK.getCode());
                rsp.setMessage("添加用户信息成功。");
            } else {
                logger.error("添加用户信息失败。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("添加用户信息失败。");
            }
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.info("添加用户信息失败：{}", convertJsonString(e));
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("添加用户信息失败。");
            return convertJsonString(rsp);
        }
    }

    /**
     * 删除用户信息
     *
     * @param userUpdateForm 删除参数
     * @return 结果
     */
    @PostMapping("/deleteUserInfo")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    @MyLog(logTitle = "删除用户信息", logMethod = "deleteUserInfo")
    public String deleteUserInfo(@RequestBody UserUpdateForm userUpdateForm) {
        logger.info("删除用户信息，请求用户名：{}，登录ip：{}", userUpdateForm.getUserName(), HttpUtils.getIpAddr(servletRequest));
        // 创建响应信息
        ResponseEntity rsp = new ResponseEntity();
        try {
            if (userUpdateForm.getRoleId1() == null || userUpdateForm.getRoleId1() != 1) {
                logger.error("操作人员必须是管理员级别。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("操作人员必须是管理员级别。");
                return convertJsonString(rsp);
            }
            if (userUpdateForm.getUserIdUpdate() == null) {
                logger.error("缺少用户id。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("缺少用户id。");
                return convertJsonString(rsp);
            }
            // 删除用户信息
            if (userService.remove(new LambdaQueryWrapper<User>().eq(User::getUserId, userUpdateForm.getUserIdUpdate()))) {
                logger.info("删除用户信息成功。");
                rsp.setCode(ResponseCode.OK.getCode());
                rsp.setMessage("删除用户信息成功。");
            } else {
                logger.error("删除用户信息失败。");
                // 返回错误
                rsp.setCode(ResponseCode.ERROR.getCode());
                rsp.setMessage("删除用户信息失败。");
            }
            return convertJsonString(rsp);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.info("删除用户信息失败：{}", convertJsonString(e));
            // 返回其他异常
            rsp.setCode(ResponseCode.ERROR.getCode());
            rsp.setMessage("删除用户信息失败。");
            return convertJsonString(rsp);
        }
    }
}
