package com.greenorange.promotion.controller.userInfo;

import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
import cn.binarywang.wx.miniapp.bean.WxMaQrcode;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.greenorange.promotion.annotation.RequiresPermission;
import com.greenorange.promotion.annotation.SysLog;
import com.greenorange.promotion.common.BaseResponse;
import com.greenorange.promotion.common.ErrorCode;
import com.greenorange.promotion.common.ResultUtils;
import com.greenorange.promotion.constant.UserConstant;
import com.greenorange.promotion.exception.ThrowUtils;
import com.greenorange.promotion.model.dto.CommonBatchRequest;
import com.greenorange.promotion.model.dto.CommonRequest;
import com.greenorange.promotion.model.dto.CommonStringRequest;
import com.greenorange.promotion.model.dto.userInfo.*;
import com.greenorange.promotion.model.entity.UserInfo;
import com.greenorange.promotion.model.entity.UserMainInfo;
import com.greenorange.promotion.model.enums.UserRoleEnum;
import com.greenorange.promotion.model.vo.userInfo.*;
import com.greenorange.promotion.model.vo.userMainInfo.UserMainInfoVO;
import com.greenorange.promotion.service.common.CommonService;
import com.greenorange.promotion.service.userInfo.UserInfoService;
import com.greenorange.promotion.service.userInfo.UserMainInfoService;
import com.greenorange.promotion.service.wechat.WechatGetQrcodeService;
import com.greenorange.promotion.utils.JWTUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 用户表 控制器
 */
@RestController
@RequestMapping("userInfo")
@Slf4j
@Tag(name = "用户管理")
@Transactional
public class UserInfoController {


    @Resource
    private UserInfoService userInfoService;


    @Resource
    private UserMainInfoService userMainInfoService;


    @Resource
    private CommonService commonService;


    @Resource
    private RedisTemplate<String, String> redisTemplate;


    @Resource
    private JWTUtils jwtUtils;


    @Resource
    private WechatGetQrcodeService wechatGetQrcodeService;



//    @PostMapping("test")
//    public BaseResponse<Boolean> test() throws IOException {
//        List<UserInfo> list = userInfoService.list();
//        Map<Long, UserInfo> map = new HashMap<>();
//        for (UserInfo userInfo : list) {
//            map.put(userInfo.getId(), userInfo);
//        }
//        List<UserMainInfo> userMainInfoList = userMainInfoService.list();
//        for (UserMainInfo userMainInfo : userMainInfoList) {
//            Long userId = userMainInfo.getUserId();
//            UserInfo userInfo = map.get(userId);
//            String userRole = userInfo.getUserRole();
//            UserRoleEnum userRoleEnum = UserRoleEnum.getEnumByValue(userRole);
//            String view = wechatGetQrcodeService.getWxQrCode(userInfo.getInvitationCode(), userRoleEnum);
//            userMainInfo.setInviteQrCode(view);
//        }
//        userMainInfoService.saveOrUpdateBatch(userMainInfoList);
//        return ResultUtils.success(true);
//    }


    /**
     * 小程序端用户校验token
     * @return 是否校验成功
     */
    @PostMapping("verify/token")
    @Operation(summary = "小程序端用户校验token", description = "参数：token, 权限：管理员（boss, admin)，方法名：verifyToken")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
    public BaseResponse<Boolean> verifyToken() {
        return ResultUtils.success(true);
    }


    /**
     * web端修改员工申请须知
     * @param commonStringRequest 修改内容
     * @return 是否修改成功
     */
    @PostMapping("modify/applyNotice")
    @Operation(summary = "web端修改员工申请须知", description = "参数：修改内容，权限：管理员（boss, admin)，方法名：modifyApplyNotice")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> modifyApplyNotice(@Valid @RequestBody CommonStringRequest commonStringRequest) {
        String applyNotice = commonStringRequest.getTemplateString();
        redisTemplate.opsForValue().set(UserConstant.APPLY_NOTICE_KEY, applyNotice);
        return ResultUtils.success(true);
    }


    /**
     * （Web端）小程序端查询员工申请须知
     * @return 是否修改成功
     */
    @PostMapping("query/applyNotice")
    @Operation(summary = "（Web端）小程序端查询员工申请须知", description = "参数：无，权限：管理员（boss, admin)，方法名：queryApplyNotice")
    public BaseResponse<String> queryApplyNotice() {
        String applyNotice = redisTemplate.opsForValue().get(UserConstant.APPLY_NOTICE_KEY);
        return ResultUtils.success(applyNotice);
    }


    /**
     * web端修改课程购买须知
     * @param commonStringRequest 修改内容
     * @return 是否修改成功
     */
    @PostMapping("modify/courseDesc")
    @Operation(summary = "web端修改课程购买须知", description = "参数：修改内容，权限：管理员（boss, admin)，方法名：modifyCourseDesc")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> modifyCourseDesc(@Valid @RequestBody CommonStringRequest commonStringRequest) {
        String courseDesc = commonStringRequest.getTemplateString();
        redisTemplate.opsForValue().set(UserConstant.COURSE_DESC_KEY, courseDesc);
        return ResultUtils.success(true);
    }


    /**
     * （Web端）小程序端查询课程购买须知
     * @return 是否修改成功
     */
    @PostMapping("query/courseDesc")
    @Operation(summary = "（Web端）小程序端查询课程购买须知", description = "参数：无，权限：管理员（boss, admin)，方法名：queryApplyNotice")
    public BaseResponse<String> queryCourseDesc() {
        String courseDesc = redisTemplate.opsForValue().get(UserConstant.COURSE_DESC_KEY);
        return ResultUtils.success(courseDesc);
    }




    /**
     * 小程序端用户修改用户昵称
     * @param commonStringRequest 昵称
     * @return 是否修改成功
     */
    @PostMapping("modify/nickname")
    @Operation(summary = "小程序端用户修改用户昵称", description = "参数：昵称，权限：管理员（boss, admin)，方法名：modifyNickname")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
    public BaseResponse<Boolean> modifyNickname(@Valid @RequestBody CommonStringRequest commonStringRequest, HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        String nickName = commonStringRequest.getTemplateString();
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getNickName, nickName);
        queryWrapper.ne(UserInfo::getId, userId);
        ThrowUtils.throwIf(userInfoService.count(queryWrapper) > 0, ErrorCode.PARAMS_ERROR, "昵称已存在");

        LambdaUpdateWrapper<UserInfo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserInfo::getId, userId).set(UserInfo::getNickName, nickName);
        userInfoService.update(updateWrapper);
        return ResultUtils.success(true);
    }


    /**
     * 小程序端用户修改用户头像
     * @param commonStringRequest 头像view值
     * @return 是否修改成功
     */
    @PostMapping("modify/avatar")
    @Operation(summary = "小程序端用户修改用户头像", description = "参数：头像view值，权限：管理员（boss, admin)，方法名：modifyUserAvatar")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
    public BaseResponse<Boolean> modifyUserAvatar(@Valid @RequestBody CommonStringRequest commonStringRequest, HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        String view = commonStringRequest.getTemplateString();
        LambdaUpdateWrapper<UserInfo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserInfo::getId, userId).set(UserInfo::getUserAvatar, view);
        userInfoService.update(updateWrapper);
        return ResultUtils.success(true);
    }



    /**
     * 小程序端用户获取验证码（用于注册）
     * @param verificationCodeGetRequest 验证码获取请求体
     * @return 验证码
     */
    @PostMapping("code/register")
    @Operation(summary = "小程序端用户获取验证码（用于注册）", description = "参数：手机号，权限：管理员（boss, admin)，方法名：getVerificationCodeForRegister")
    public BaseResponse<String> getVerificationCodeForRegister(@Valid @RequestBody VerificationCodeGetRequest verificationCodeGetRequest) {
        String verificationCode = userInfoService.getVerificationCodeForRegister(verificationCodeGetRequest);
        return ResultUtils.success(verificationCode);
    }


    /**
     * 小程序端用户获取验证码（用于密码登录和忘记密码）
     * @param verificationCodeGetRequest 验证码获取请求体
     * @return 验证码
     */
    @PostMapping("code/pwd")
    @Operation(summary = "小程序端用户获取验证码（用于密码登录和忘记密码）", description = "参数：手机号，权限：管理员（boss, admin)，方法名：getVerificationCode")
//    @SysLog(title = "用户管理", content = "小程序端用户获取验证码")
    public BaseResponse<String> getVerificationCode(@Valid @RequestBody VerificationCodeGetRequest verificationCodeGetRequest) {
        String verificationCode = userInfoService.getVerificationCodeForPwdLogin(verificationCodeGetRequest);
        return ResultUtils.success(verificationCode);
    }


    /**
     * 小程序端用户根据id获取上级邀请码
     * @param commonRequest 用户id
     * @return 上级邀请码
     */
    @PostMapping("inviteCode")
    @Operation(summary = "小程序端用户根据id获取上级邀请码", description = "参数：用户id，权限：管理员（boss, admin)，方法名：getParentUserInviteCode")
    public BaseResponse<String> getParentUserInviteCode(@Valid @RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        UserInfo userInfo = userInfoService.getById(id);
        return ResultUtils.success(userInfo.getInvitationCode());
    }



    /**
     * 小程序端用户注册
     * @param userInfoRegisterRequest 小程序用户注册请求体
     * @return 是否注册成功
     */
    @PostMapping("register")
    @Operation(summary = "小程序端用户注册", description = "参数：小程序用户注册请求体，权限：管理员（boss, admin)，方法名：userInfoMiniRegister")
    public BaseResponse<Boolean> userInfoMiniRegister(@Valid @RequestBody UserInfoRegisterRequest userInfoRegisterRequest) {
        userInfoService.userInfoMiniRegister(userInfoRegisterRequest);
        return ResultUtils.success(true);
    }



    /**
     * 小程序端用户密码登录
     * @param userInfoMiniPasswordLoginRequest 小程序用户密码登录请求体
     * @return token
     */
    @PostMapping("mini/pwd/login")
    @Operation(summary = "小程序端用户密码登录", description = "参数：小程序用户密码登录请求体，权限：管理员（boss, admin)，方法名：userInfoMiniLogin")
    public BaseResponse<String> userInfoMiniLoginByPwd(@Valid @RequestBody UserInfoMiniPasswordLoginRequest userInfoMiniPasswordLoginRequest) {
        String token = userInfoService.userInfoMiniLoginByPwd(userInfoMiniPasswordLoginRequest);
        return ResultUtils.success(token);
    }



    /**
     * 小程序端用户验证码登录
     * @param userInfoMiniVerifyCodeLoginRequest 小程序用户验证码登录请求体
     * @return token
     */
    @PostMapping("mini/vcd/login")
    @Operation(summary = "小程序端用户验证码登录", description = "参数：小程序用户验证码登录请求体，权限：管理员（boss, admin)，方法名：userInfoMiniLoginByVcd")
//    @SysLog(title = "用户管理", content = "小程序端用户验证码登录")
    public BaseResponse<String> userInfoMiniLoginByVcd(@Valid @RequestBody UserInfoMiniVerifyCodeLoginRequest userInfoMiniVerifyCodeLoginRequest) {
        String token = userInfoService.userInfoMiniLoginByVcd(userInfoMiniVerifyCodeLoginRequest);
        return ResultUtils.success(token);
    }


    /**
     * 小程序用户重置密码（外部）
     * @param userInfoResetRequest 小程序用户密码重置请求体
     * @return 是否重置成功
     */
    @PostMapping("mini/out/reset/pwd")
    @Operation(summary = "小程序用户重置密码（外部）", description = "参数：小程序用户密码重置请求体，权限：管理员（boss, admin)，方法名：userInfoMiniOuterResetPwd")
    public BaseResponse<Boolean> userInfoMiniOuterResetPwd(@Valid @RequestBody UserInfoResetRequest userInfoResetRequest) {
        userInfoService.userInfoMiniResetPwd(userInfoResetRequest, false);
        return ResultUtils.success(true);
    }


    /**
     * 小程序用户重置密码（内部）
     * @param userInfoResetRequest 小程序用户密码重置请求体
     * @return 是否重置成功
     */
    @PostMapping("mini/in/reset/pwd")
    @Operation(summary = "小程序用户重置密码（内部）", description = "参数：小程序用户密码重置请求体，权限：管理员（boss, admin)，方法名：userInfoMiniInnerResetPwd")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "用户管理", content = "小程序用户重置密码（内部）")
    public BaseResponse<Boolean> userInfoMiniInnerResetPwd(@Valid @RequestBody UserInfoResetRequest userInfoResetRequest) {
        userInfoService.userInfoMiniResetPwd(userInfoResetRequest, true);
        return ResultUtils.success(true);
    }





    /**
     * web端用户根据jwt获取用户信息
     * @return 用户信息
     */
    @GetMapping("get/jwt/web")
    @Operation(summary = "web端用户根据jwt获取用户信息", description = "参数：无，权限：管理员（boss, admin)，方法名：getWebUserInfoByJWT")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "用户管理", content = "web端用户根据jwt获取用户信息")
    public BaseResponse<UserInfoVO> getWebUserInfoByJWT(HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        UserInfo userInfo = userInfoService.getById(userId);
        UserInfoVO userInfoVO = commonService.copyProperties(userInfo, UserInfoVO.class);
        return ResultUtils.success(userInfoVO);
    }



    /**
     * 小程序端用户根据jwt获取用户信息
     * @return 用户信息
     */
    @GetMapping("get/jwt")
    @Operation(summary = "小程序端用户根据jwt获取用户信息", description = "参数：无，权限：管理员（boss, admin)，方法名：getMiniUserInfoByJWT")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "用户管理", content = "小程序端用户根据jwt获取用户信息")
    public BaseResponse<UserInfoVO> getMiniUserInfoByJWT(HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        UserInfo userInfo = userInfoService.getById(userId);
        UserInfoVO userInfoVO = commonService.copyProperties(userInfo, UserInfoVO.class);
        return ResultUtils.success(userInfoVO);
    }


    /**
     * 小程序端用户根据jwt获取用户主要信息
     * @return 用户信息
     */
    @GetMapping("get/main/jwt")
    @Operation(summary = "小程序端用户根据jwt获取用户主要信息", description = "参数：无，权限：管理员（boss, admin)，方法名：getMiniUserInfoByJWT")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "用户管理", content = "小程序端用户根据jwt获取用户主要信息")
    public BaseResponse<UserMainInfoVO> getMiniUserMainInfoByJWT(HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        LambdaQueryWrapper<UserMainInfo> userMainInfoLambdaQueryWrapper = commonService.buildQueryWrapperByField(UserMainInfo::getUserId, userId, userMainInfoService);
        UserMainInfo userMainInfo = userMainInfoService.getOne(userMainInfoLambdaQueryWrapper);
        UserMainInfoVO userMainInfoVO = commonService.copyProperties(userMainInfo, UserMainInfoVO.class);
        return ResultUtils.success(userMainInfoVO);
    }




    /**
     * 小程序端用户退出登录(用户退出时将 token 加入 Redis 黑名单)
     * @return 是否退出登录成功
     */
    @GetMapping("mini/logout")
    @Operation(summary = "小程序端用户退出登录", description = "参数：JWT，权限：管理员（boss, admin)，方法名：userInfoMiniLogout")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
    public BaseResponse<Boolean> userInfoMiniLogout(@RequestHeader("Authorization") String token) {
        // 获取token的过期时间
        DecodedJWT decodedJWT = jwtUtils.verify(token);
        long expirationTime = decodedJWT.getExpiresAt().getTime() - System.currentTimeMillis();
        // 将token存入Redis黑名单，并设置过期时间与token一致
        redisTemplate.opsForValue().set(token, token, expirationTime, TimeUnit.MILLISECONDS);
        return ResultUtils.success(true);
    }



    /**
     * web端管理员登录
     * @param userInfoLoginRequest web用户登录请求体
     * @return 是否登录成功
     */
    @PostMapping("login")
    @Operation(summary = "web端管理员登录", description = "参数：web用户登录请求体，权限：管理员（boss, admin)，方法名：userInfoLogin")
//    @SysLog(title = "用户管理", content = "web端管理员登录")
    public BaseResponse<String> userInfoLogin(@Valid @RequestBody UserInfoLoginRequest userInfoLoginRequest) {
        String token = userInfoService.userInfoLogin(userInfoLoginRequest);
        return ResultUtils.success(token);
    }




    /**
     * web端管理员退出登录(用户退出时将 token 加入 Redis 黑名单)
     * @return 是否退出登录成功
     */
    @GetMapping("logout")
    @Operation(summary = "web端管理员退出登录", description = "参数：JWT，权限：管理员（boss, admin)，方法名：userInfoLogout")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "用户管理", content = "web端管理员退出登录")
    public BaseResponse<Boolean> userInfoLogout(@RequestHeader("Authorization") String token) {
        // 获取token的过期时间
        DecodedJWT decodedJWT = jwtUtils.verify(token);
        long expirationTime = decodedJWT.getExpiresAt().getTime() - System.currentTimeMillis();
        // 将token存入Redis黑名单，并设置过期时间与token一致
        redisTemplate.opsForValue().set(token, token, expirationTime, TimeUnit.MILLISECONDS);
        return ResultUtils.success(true);
    }






    /**
     * web端管理员添加用户
     * @param userInfoAddRequest 用户表添加请求体
     * @return 是否添加成功
     */
    @PostMapping("add")
    @Operation(summary = "web端管理员添加用户", description = "参数：用户表添加请求体，权限：管理员（boss, admin)，方法名：addUserInfo")
    @RequiresPermission(mustRole = UserConstant.BOSS_ROLE)
//    @SysLog(title = "用户管理", content = "web端管理员添加用户")
    public BaseResponse<Boolean> addUserInfo(@Valid @RequestBody UserInfoAddRequest userInfoAddRequest) {
        UserInfo userInfo = commonService.copyProperties(userInfoAddRequest, UserInfo.class);
        userInfo.setParentUserId(-1L);
        userInfo.setUserRole(UserConstant.ADMIN_ROLE);
        userInfoService.save(userInfo);
        return ResultUtils.success(true);
    }



    /**
     * web端管理员根据id修改用户信息
     * @param userInfoUpdateRequest 用户表更新请求体
     * @return 是否更新成功
     */
    @PostMapping("update")
    @Operation(summary = "web端管理员更新用户", description = "参数：用户表更新请求体，权限：管理员（boss, admin)，方法名：updateUserInfo")
    @RequiresPermission(mustRole = UserConstant.BOSS_ROLE)
//    @SysLog(title = "用户管理", content = "web端管理员根据id修改用户信息")
    public BaseResponse<Boolean> updateUserInfo(@Valid @RequestBody UserInfoUpdateRequest userInfoUpdateRequest) {
        UserInfo userInfo = commonService.copyProperties(userInfoUpdateRequest, UserInfo.class);
        userInfoService.updateById(userInfo);
        return ResultUtils.success(true);
    }


    /**
     * web端管理员根据id删除用户
     * @param commonRequest 用户表删除请求体
     * @return 是否删除成功
     */
    @PostMapping("delete")
    @Operation(summary = "web端管理员根据id删除用户", description = "参数：用户表删除请求体，权限：管理员（boss, admin)，方法名：delUserInfo")
    @RequiresPermission(mustRole = UserConstant.BOSS_ROLE)
//    @SysLog(title = "用户管理", content = "web端管理员根据id删除用户表")
    public BaseResponse<Boolean> delUserInfo(@Valid @RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        userInfoService.removeById(id);
        return ResultUtils.success(true);
    }



    /**
     * web端管理员批量删除用户
     * @param commonBatchRequest 用户表批量删除请求体
     * @return 是否删除成功
     */
    @PostMapping("delBatch")
    @Operation(summary = "web端管理员批量删除用户", description = "参数：用户表批量删除请求体，权限：管理员（boss, admin)，方法名:delBatchUserInfo")
    @RequiresPermission(mustRole = UserConstant.BOSS_ROLE)
//    @SysLog(title = "用户管理", content = "web端管理员批量删除用户表")
    public BaseResponse<Boolean> delBatchUserInfo(@Valid @RequestBody CommonBatchRequest commonBatchRequest) {
        List<Long> ids = commonBatchRequest.getIds();
        userInfoService.removeByIds(ids);
        return ResultUtils.success(true);
    }




    /**
     * web端管理员根据id查询用户
     * @param commonRequest 用户表查询请求体
     * @return 用户表信息
     */
    @PostMapping("queryById")
    @Operation(summary = "web端管理员根据id查询用户", description = "参数：用户表查询请求体，权限：管理员（boss, admin)，方法名:queryUserInfoById")
    @RequiresPermission(mustRole = UserConstant.BOSS_ROLE)
//    @SysLog(title = "用户管理", content = "web端管理员根据id查询用户")
    public BaseResponse<UserInfoVO> queryUserInfoById(@Valid @RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        UserInfo userInfo = userInfoService.getById(id);
        ThrowUtils.throwIf(userInfo == null, ErrorCode.OPERATION_ERROR, "当前用户不存在");
        UserInfoVO userInfoVO = commonService.copyProperties(userInfo, UserInfoVO.class);
        return ResultUtils.success(userInfoVO);
    }




    /**
     * Web端管理员分页查询用户
     * @param userInfoQueryRequest 用户表查询请求体
     * @return 用户表列表
     */
    @PostMapping("page")
    @Operation(summary = "Web端管理员分页查询用户", description = "参数：用户表查询请求体，权限：管理员（boss, admin)，方法名:listUserInfoByPage")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "用户管理", content = "Web端管理员分页查看用户")
    public BaseResponse<Page<UserInfoVO>> listUserInfoByPage(@Valid @RequestBody UserInfoQueryRequest userInfoQueryRequest) {
        long current = userInfoQueryRequest.getCurrent();
        long pageSize = userInfoQueryRequest.getPageSize();
        QueryWrapper<UserInfo> queryWrapper = userInfoService.getQueryWrapper(userInfoQueryRequest);
        Page<UserInfo> page = userInfoService.page(new Page<>(current, pageSize), queryWrapper);
        List<UserInfo> userInfoList = page.getRecords();
        List<UserInfoVO> userInfoVOList = commonService.convertList(userInfoList, UserInfoVO.class);
        Page<UserInfoVO> voPage = new Page<>(current, pageSize);
        voPage.setRecords(userInfoVOList);
        voPage.setPages(page.getPages());
        voPage.setTotal(page.getTotal());
        return ResultUtils.success(voPage);
    }



    /**
     * 小程序端用户获取上级用户信息
     * @return 上级用户信息
     */
    @PostMapping("getSuper")
    @Operation(summary = "小程序端用户获取上级用户信息", description = "参数：用户表查询请求体，权限：管理员（boss, admin)，方法名:queryUserInfoById")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
    public BaseResponse<SuperUserInfoVO> getSuperUserInfo(HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        UserInfo userInfo = userInfoService.getById(userId);
        Long parentUserId = userInfo.getParentUserId();
        if (parentUserId != 0) {
            userInfo = userInfoService.getById(parentUserId);
        }
        SuperUserInfoVO superUserInfoVO = commonService.copyProperties(userInfo, SuperUserInfoVO.class);
        return ResultUtils.success(superUserInfoVO);
    }




    /**
     * web端管理员查询主管列表
     * @return 主管列表
     */
    @PostMapping("query/supervisor")
    @Operation(summary = "web端管理员查询主管列表", description = "参数：无，权限：管理员（boss, admin)，方法名:querySupervisorList")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<List<SupervisorUserVO>> querySupervisorList() {
        // 获取用户基本信息和主要信息表
        List<UserInfo> userInfoList = commonService.findByFieldEqTargetField(UserInfo::getUserRole, UserRoleEnum.SUPERVISOR.getValue(), userInfoService);
        List<UserMainInfo> userMainInfoList = commonService.findByFieldInTargetField(userInfoList, userMainInfoService, UserInfo::getId, UserMainInfo::getUserId);
        // 封装Map, 键: 用户id，值：用户信息
        Map<Long, UserInfo> userInfoMap = new HashMap<>();
        for (UserInfo userInfo : userInfoList) {
            userInfoMap.put(userInfo.getId(), userInfo);
        }
        List<SupervisorUserVO> supervisorUserVOS = new ArrayList<>();
        for (UserMainInfo userMainInfo : userMainInfoList) {
            SupervisorUserVO supervisorUserVO = commonService.copyProperties(userMainInfo, SupervisorUserVO.class);
            UserInfo userInfo = userInfoMap.get(userMainInfo.getUserId());
            BeanUtils.copyProperties(userInfo, supervisorUserVO);
            supervisorUserVOS.add(supervisorUserVO);
        }
        return ResultUtils.success(supervisorUserVOS);
    }




    /**
     * web端管理员根据主管id查询员工列表
     * @param commonRequest 主管id
     * @return 员工列表
     */
    @PostMapping("query/staff")
    @Operation(summary = "web端管理员根据主管id查询员工列表", description = "参数：主管id，权限：管理员（boss, admin)，方法名:queryStaffListBySupervisorId")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<List<StaffUserVO>> queryStaffListBySupervisorId(@Valid @RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        List<UserInfo> userInfoList = commonService.findByFieldEqTargetField(UserInfo::getParentUserId, id, userInfoService);
        List<UserMainInfo> userMainInfoList = commonService.findByFieldInTargetField(userInfoList, userMainInfoService, UserInfo::getId, UserMainInfo::getUserId);
        // 封装Map, 键: 用户id，值：用户信息
        Map<Long, UserInfo> userInfoMap = new HashMap<>();
        for (UserInfo userInfo : userInfoList) {
            userInfoMap.put(userInfo.getId(), userInfo);
        }
        List<StaffUserVO> staffUserVOS = new ArrayList<>();
        for (UserMainInfo userMainInfo : userMainInfoList) {
            StaffUserVO staffUserVO = commonService.copyProperties(userMainInfo, StaffUserVO.class);
            UserInfo userInfo = userInfoMap.get(userMainInfo.getUserId());
            BeanUtils.copyProperties(userInfo, staffUserVO);
            staffUserVOS.add(staffUserVO);
        }
        return ResultUtils.success(staffUserVOS);
    }


    /**
     * web端管理员查看经理信息
     * @return 经理信息
     */
    @PostMapping("query/manager")
    @Operation(summary = "web端管理员查看经理信息", description = "参数：无，权限：管理员（boss, admin)，方法名:queryManagerInfo")
    @RequiresPermission(mustRole = UserConstant.BOSS_ROLE)
    public BaseResponse<ManagerUserInfoVO> queryManagerInfo() {
        LambdaQueryWrapper<UserInfo> userInfoLambdaQueryWrapper = commonService.buildQueryWrapperByField(UserInfo::getUserRole, UserConstant.MANAGER_ROLE, userInfoService);
        UserInfo managerUserInfo = userInfoService.getOne(userInfoLambdaQueryWrapper);
        ManagerUserInfoVO managerUserInfoVO = commonService.copyProperties(managerUserInfo, ManagerUserInfoVO.class);
        return ResultUtils.success(managerUserInfoVO);
    }


    /**
     * web端管理员修改经理信息
     * @return 是否修改成功
     */
    @PostMapping("modify/manager")
    @Operation(summary = "web端管理员修改经理信息", description = "参数：无，权限：管理员（boss, admin)，方法名:modifyManagerInfo")
    @RequiresPermission(mustRole = UserConstant.BOSS_ROLE)
    public BaseResponse<Boolean> modifyManagerInfo(@Valid @RequestBody ManagerUserInfoUpdateRequest managerUserInfoUpdateRequest) {
        UserInfo userInfo = commonService.copyProperties(managerUserInfoUpdateRequest, UserInfo.class);
        userInfoService.updateById(userInfo);
        return ResultUtils.success(true);
    }

}
