package com.gxwebsoft.common.system.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
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.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.config.ConfigProperties;
import com.gxwebsoft.common.core.security.JwtSubject;
import com.gxwebsoft.common.core.security.JwtUtil;
import com.gxwebsoft.common.core.utils.CommonUtil;
import com.gxwebsoft.common.core.web.*;
import com.gxwebsoft.common.system.entity.*;
import com.gxwebsoft.common.system.param.LoginParam;
import com.gxwebsoft.common.system.param.UserImportParam;
import com.gxwebsoft.common.system.param.UserParam;
import com.gxwebsoft.common.system.result.LoginResult;
import com.gxwebsoft.common.system.service.*;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.apache.poi.ss.usermodel.Workbook;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户控制器
 *
 * @author WebSoft
 * @since 2018-12-24 16:10:41
 */
@Slf4j
@Tag(name = "用户")
@RestController
@RequestMapping("/api/system/user")
public class UserController extends BaseController {
    @Resource
    private UserService userService;
    @Resource
    private RoleService roleService;
    @Resource
    private OrganizationService organizationService;
    @Resource
    private DictionaryDataService dictionaryDataService;
    @Resource
    private UserRoleService userRoleService;
    @Resource
    private ConfigProperties configProperties;
    @Resource
    private LoginRecordService loginRecordService;
    @Resource
    private UserSyncService userSyncService;

    @PreAuthorize("hasAuthority('sys:auth:user')")
    @Operation(summary = "分页查询用户")
    @GetMapping("/page")
    public ApiResult<PageResult<User>> page(UserParam param) {
        return success(userService.pageRel(param));
    }

    @PreAuthorize("hasAuthority('sys:auth:user')")
    @Operation(summary = "查询全部用户")
    @GetMapping()
    public ApiResult<List<User>> list(UserParam param) {
        return success(userService.listRel(param));
    }

    @Operation(summary = "查询全部用户(无需登录)")
    @GetMapping("/withoutAuth")
    public ApiResult<List<User>> listWithoutAuth(UserParam param) {
        return success(userService.listRel(param));
    }

    @PreAuthorize("hasAuthority('sys:auth:user')")
    @Operation(summary = "根据id查询用户")
    @GetMapping("/{id}")
    public ApiResult<User> get(@PathVariable("id") Integer id) {
        return success(userService.getByIdRel(id));
    }

//    @PreAuthorize("hasAuthority('sys:auth:user')")
    @Operation(summary = "根据手机号码查询用户")
    @GetMapping("/getByPhone/{phone}")
    public ApiResult<User> getByPhone(@PathVariable("phone") String phone) {
        return success(userService.getByPhone(phone));
    }

    @Operation(summary = "根据UserId查询用户(无需登录)")
    @GetMapping("/getByUserId/{userId}")
    public ApiResult<User> getByUserId(@PathVariable("userId") String userId) {
        return success(userService.getAllByUserId(userId));
    }

    @Operation(summary = "根据unionid查询用户")
    @GetMapping("/getByUnionid/{unionid}")
    public ApiResult<User> getByUnionid(@PathVariable("unionid") String unionid) {
        return success(userService.getByUnionId(new UserParam() {{
            setUnionid(unionid);
        }}));
    }

    @Operation(summary = "当前登录用户信息")
    @GetMapping("/info")
    public ApiResult<User> getLoginUserInfo() {
        return success(getLoginUser());
    }


    @Operation(summary = "手机号登录(测试用)")
    @PostMapping("/loginByPhoneForTest")
    public ApiResult<?> loginByPhoneForTest(@RequestBody User user) {
        User getLoginUser = userService.getByPhone(user.getPhone());
        if (!user.getPhoneLoginCode().equals("1700083")) return fail("验证码错误");
        String access_token = JwtUtil.buildToken(new JwtSubject(getLoginUser.getUsername(), getLoginUser.getTenantId()),
                configProperties.getTokenExpireTime(), configProperties.getTokenKey());
        return success("登录成功", new LoginResult(access_token, user));
    }

    @Operation(summary = "手机号注册")
    @PostMapping("/regByPhone")
    public ApiResult<?> regByPhone(@RequestBody User user) {
        user.setPassword(userService.encodePassword(user.getPassword()));
        // 排重
        final User byPhone = userService.getByPhone(user.getPhone());
        if (ObjectUtil.isNotEmpty(byPhone)) {
            return fail("该手机号码已存在");
        }
        if (userService.saveUser(user)) {
            // 同步到 websopy
            userSyncService.syncUserToWebsopy(user);
            return success("添加成功", user.getUserId());
        }
        return fail("添加失败");
    }

    @PreAuthorize("hasAuthority('sys:user:save')")
    @Operation(summary = "添加用户")
    @PostMapping()
    public ApiResult<?> add(@RequestBody User user) {
        user.setStatus(0);
        user.setPassword(userService.encodePassword(user.getPassword()));
        // 排重
        final User byPhone = userService.getByPhone(user.getPhone());
        if (ObjectUtil.isNotEmpty(byPhone)) {
            return fail("该手机号码已存在");
        }
        if (userService.saveUser(user)) {
            // 同步到 websopy
            userSyncService.syncUserToWebsopy(user);
            return success("添加成功", user.getUserId());
        }
        return fail("添加失败");
    }

    @PreAuthorize("hasAuthority('sys:user:save')")
    @Operation(summary = "批量添加用户")
    @PostMapping("/batch")
    public ApiResult<?> saveBatch(@RequestBody List<User> userList) {
        userList.forEach(d -> {
            d.setStatus(0);
            if (d.getPassword() != null) {
                d.setPassword(userService.encodePassword(d.getPassword()));
            }
        });

        final Set<String> collect = userList.stream().map(User::getPhone).collect(Collectors.toSet());
        final List<User> list = userService.list(new LambdaQueryWrapper<User>().in(User::getPhone, collect).select(User::getPhone));
        final Map<String, List<User>> phoneCollect = list.stream().collect(Collectors.groupingBy(User::getPhone));
        userList.removeIf(d -> phoneCollect.containsKey(d.getPhone()));

        if (userService.saveBatch(userList)) {
            // 同步到 websopy（异步处理，不阻塞响应）
            userList.forEach(user -> userSyncService.syncUserToWebsopy(user));
            return success("添加成功");
        }
        return fail("添加失败");
    }

//    @PreAuthorize("hasAuthority('sys:user:save')")
    @Operation(summary = "批量添加用户并返回userId")
    @PostMapping("/batchBackUserId")
    public ApiResult<?> saveBatchBackUserId(@RequestBody List<User> userList) {
        userList.forEach(d -> {
            d.setStatus(0);
            d.setPassword(userService.encodePassword(d.getPassword()));
        });
        final Set<String> phones = userList.stream().map(User::getPhone).collect(Collectors.toSet());
        if (userService.saveBatch(userList)) {
            final UserParam userParam = new UserParam();
            userParam.setPhones(phones);
            userParam.setLimit(500L);
            final PageResult<User> result = userService.pageRel(userParam);
            final Set<Integer> collect = result.getList().stream().map(User::getUserId).collect(Collectors.toSet());
            // 同步到 websopy（异步处理，不阻塞响应）
            userList.forEach(user -> userSyncService.syncUserToWebsopy(user));
            return success("添加成功", collect);
        }
        return fail("添加失败");
    }

    //    @PreAuthorize("hasAuthority('sys:user:update')")
    @OperationLog
    @Operation(summary = "修改用户")
    @PutMapping()
    public ApiResult<?> update(@RequestBody User user) {
        user.setStatus(null);
        user.setUsername(null);
        if (user.getPassword() != null) {
            String pwd = userService.encodePassword(user.getPassword());
            User originData = userService.getByIdRel(user.getUserId());
            if(!pwd.equals(originData.getPassword())) {
                user.setPassword(pwd);
            }else {
                user.setPassword(null);
            }
        }
        // 同步管理员的产品套餐ID
        if(user.getIsAdmin() != null){
          final User superAdmin = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getIsAdmin, 1).eq(User::getUsername, "superAdmin").last("limit 1"));
          if (superAdmin != null) user.setTemplateId(superAdmin.getTemplateId());
        }
        if (userService.updateUser(user)) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @OperationLog
    @Operation(summary = "修改用户(无需登录)")
    @PutMapping("/updateWithoutLogin")
    public ApiResult<?> updateWithoutLogin(@RequestBody User user) {
        if (userService.updateUser(user)) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @PreAuthorize("hasAuthority('sys:user:remove')")
    @OperationLog
    @Operation(summary = "删除用户")
    @DeleteMapping("/{id}")
    public ApiResult<?> remove(@PathVariable("id") Integer id) {
        if (userService.removeById(id)) {
            return success("删除成功");
        }
        return fail("删除失败");
    }

    @PreAuthorize("hasAuthority('sys:user:update')")
    @OperationLog
    @Operation(summary = "批量修改用户")
    @PutMapping("/batch")
    public ApiResult<?> removeBatch(@RequestBody BatchParam<User> batchParam) {
        if (batchParam.update(userService, User::getUserId)) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @PreAuthorize("hasAuthority('sys:user:remove')")
    @OperationLog
    @Operation(summary = "批量删除用户")
    @Transactional(rollbackFor = {Exception.class})
    @DeleteMapping("/batch")
    public ApiResult<?> deleteBatch(@Parameter(description = "要删除的用户ID数组", required = true) @RequestBody List<Integer> ids) {
        if (userService.removeByIds(ids)) {
            return success("删除成功");
        }
        return fail("删除失败");
    }

    @PreAuthorize("hasAuthority('sys:user:update')")
    @OperationLog
    @Operation(summary = "修改用户状态")
    @PutMapping("/status")
    public ApiResult<?> updateStatus(@RequestBody User user) {
        if (user.getUserId() == null || user.getStatus() == null || !Arrays.asList(0, 1).contains(user.getStatus())) {
            return fail("参数不正确");
        }
        User u = new User();
        u.setUserId(user.getUserId());
        u.setStatus(user.getStatus());
        if (userService.updateById(u)) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @PreAuthorize("hasAuthority('sys:auth:user')")
    @Operation(summary = "查询用户审核信息")
    @GetMapping("/audit/{userId}")
    public ApiResult<Map<String, Object>> getAuditInfo(@PathVariable("userId") Integer userId) {
        User user = userService.getByIdRel(userId);
        if (user == null) {
            return fail("用户不存在",null);
        }
        Map<String, Object> result = new HashMap<>();
        result.put("userId", user.getUserId());
        result.put("auditStatus", user.getAuditStatus());
        result.put("rejectReason", user.getRejectReason());
        return success(result);
    }

    @PreAuthorize("hasAuthority('sys:user:update')")
    @OperationLog
    @Operation(summary = "审核用户注册(通过/拒绝)")
    @PutMapping("/audit")
    public ApiResult<?> auditUser(@RequestBody User user) {
        if (user.getUserId() == null || user.getAuditStatus() == null
                || !Arrays.asList(0, 1, 2).contains(user.getAuditStatus())) {
            return fail("参数不正确");
        }
        User update = new User();
        update.setUserId(user.getUserId());
        update.setAuditStatus(user.getAuditStatus());
        // 拒绝时必须填写驳回原因
        if (user.getAuditStatus() == 2) {
            if (StrUtil.isBlank(user.getRejectReason())) {
                return fail("驳回时请填写原因");
            }
            update.setRejectReason(user.getRejectReason());
        } else {
            // 通过或重新设为待审核时清除驳回原因
            update.setRejectReason(null);
        }
        if (userService.updateById(update)) {
            return success(user.getAuditStatus() == 1 ? "审核通过" : "已拒绝");
        }
        return fail("操作失败");
    }

    @PreAuthorize("hasAuthority('sys:user:update')")
    @OperationLog
    @Operation(summary = "修改推荐状态")
    @PutMapping("/recommend")
    public ApiResult<?> updateRecommend(@RequestBody User user) {
        if (user.getUserId() == null || user.getRecommend() == null || !Arrays.asList(0, 1).contains(user.getRecommend())) {
            return fail("参数不正确");
        }
        User u = new User();
        u.setUserId(user.getUserId());
        u.setRecommend(user.getRecommend());
        if (userService.updateById(u)) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @PreAuthorize("hasAuthority('sys:userRole:save')")
    @OperationLog
    @Operation(summary = "设为开发者(审核通过时标记，不新增角色)")
    @PutMapping("/developer/{userId}")
    public ApiResult<?> setDeveloper(@PathVariable("userId") Integer userId) {
        if (userId == null) {
            return fail("参数不正确");
        }
        if (userService.markAsDeveloper(userId)) {
            return success("已设为开发者");
        }
        return fail("操作失败");
    }

    @PreAuthorize("hasAuthority('sys:user:update')")
    @OperationLog
    @Operation(summary = "批量修改用户状态")
    @PutMapping("/status/batch")
    public ApiResult<?> updateStatusBatch(@RequestBody BatchParam<Integer> batchParam) {
        if (!Arrays.asList(0, 1).contains(batchParam.getData())) {
            return fail("状态值不正确");
        }
        if (userService.update(new LambdaUpdateWrapper<User>()
                .in(User::getUserId, batchParam.getIds())
                .set(User::getStatus, batchParam.getData()))) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @PreAuthorize("hasAuthority('sys:user:update')")
    @OperationLog
    @Operation(summary = "重置密码")
    @PutMapping("/password")
    public ApiResult<?> resetPassword(@RequestBody User user) {
        if (user.getUserId() == null || StrUtil.isBlank(user.getPassword())) {
            return fail("参数不正确");
        }
        User u = new User();
        u.setUserId(user.getUserId());
        u.setPassword(userService.encodePassword(user.getPassword()));
        if (userService.updateById(u)) {
            return success("重置成功");
        } else {
            return fail("重置失败");
        }
    }

    @PreAuthorize("hasAuthority('sys:user:update')")
    @OperationLog
    @Operation(summary = "批量重置密码")
    @PutMapping("/password/batch")
    public ApiResult<?> resetPasswordBatch(@RequestBody BatchParam<String> batchParam) {
        if (batchParam.getIds() == null || batchParam.getIds().size() == 0) {
            return fail("请选择用户");
        }
        if (batchParam.getData() == null) {
            return fail("请输入密码");
        }
        if (userService.update(new LambdaUpdateWrapper<User>()
                .in(User::getUserId, batchParam.getIds())
                .set(User::getPassword, userService.encodePassword(batchParam.getData())))) {
            return success("重置成功");
        } else {
            return fail("重置失败");
        }
    }

    @Operation(summary = "检查用户是否存在")
    @GetMapping("/existence")
    public ApiResult<?> existence(ExistenceParam<User> param) {
        if (param.isExistence(userService, User::getUserId)) {
            return success(param.getValue() + "已存在");
        }
        return fail(param.getValue() + "不存在");
    }

    /**
     * excel导入用户
     */
    @PreAuthorize("hasAuthority('sys:user:save')")
    @Operation(summary = "导入用户")
    @PostMapping("/import")
    public ApiResult<?> importBatch(MultipartFile file) {
        ImportParams importParams = new ImportParams();
        // 设置标题行，跳过第一行表头
        importParams.setTitleRows(1);
        importParams.setHeadRows(1);

        try {
            List<UserImportParam> list = ExcelImportUtil.importExcel(file.getInputStream(),
                    UserImportParam.class, importParams);

            if (list == null || list.isEmpty()) {
                return fail("导入文件为空", null);
            }

            // 过滤掉空行和无效数据
            list = list.stream()
                    .filter(param -> param.getUsername() != null && !param.getUsername().trim().isEmpty())
                    .collect(Collectors.toList());

            if (list.isEmpty()) {
                return fail("没有有效的用户数据", null);
            }

            // 简化验证：只检查必填字段
            for (UserImportParam param : list) {
                if (param.getPassword() == null || param.getPassword().trim().isEmpty()) {
                    return fail("用户 " + param.getUsername() + " 的密码不能为空", null);
                }
            }

            // 校验账号是否重复
            if (CommonUtil.checkRepeat(list, UserImportParam::getUsername)) {
                return fail("Excel中账号存在重复", null);
            }

            // 校验手机号是否重复（只验证非空的手机号）
            List<UserImportParam> listWithPhone = list.stream()
                    .filter(param -> param.getPhone() != null && !param.getPhone().trim().isEmpty())
                    .collect(Collectors.toList());
            if (!listWithPhone.isEmpty() && CommonUtil.checkRepeat(listWithPhone, UserImportParam::getPhone)) {
                return fail("Excel中手机号存在重复", null);
            }

            // 获取已存在的用户账号，用于跳过处理
            List<String> existingUsernames = userService.list(new LambdaQueryWrapper<User>().in(User::getUsername,
                    list.stream().map(UserImportParam::getUsername).collect(Collectors.toList())))
                    .stream().map(User::getUsername).collect(Collectors.toList());

            // 检查手机号是否已存在（只检查非空手机号）
            List<String> phonesToCheck = list.stream()
                    .map(UserImportParam::getPhone)
                    .filter(phone -> phone != null && !phone.trim().isEmpty())
                    .collect(Collectors.toList());

            final List<String> existingPhones;
            if (!phonesToCheck.isEmpty()) {
                existingPhones = userService.list(new LambdaQueryWrapper<User>().in(User::getPhone, phonesToCheck))
                        .stream().map(User::getPhone).collect(Collectors.toList());
            } else {
                existingPhones = new ArrayList<>();
            }

            // 分离新用户和已存在用户（账号或手机号已存在都算已存在）
            List<UserImportParam> newUsers = list.stream()
                    .filter(param -> !existingUsernames.contains(param.getUsername()) &&
                            (param.getPhone() == null || param.getPhone().trim().isEmpty() ||
                             !existingPhones.contains(param.getPhone())))
                    .collect(Collectors.toList());

            // 收集跳过的用户（账号已存在或手机号已存在）
            List<String> skippedUsers = new ArrayList<>();
            for (UserImportParam param : list) {
                if (existingUsernames.contains(param.getUsername())) {
                    skippedUsers.add(param.getUsername() + "(账号已存在)");
                } else if (param.getPhone() != null && !param.getPhone().trim().isEmpty() &&
                          existingPhones.contains(param.getPhone())) {
                    skippedUsers.add(param.getUsername() + "(手机号已存在)");
                }
            }

            // 创建用户列表（只处理新用户）
            List<User> users = new ArrayList<>();
            for (UserImportParam one : newUsers) {
                User u = new User();
                u.setStatus(0);
                u.setUsername(one.getUsername());
                u.setUserCode(one.getUserCode());
                u.setPassword(userService.encodePassword(one.getPassword()));
                u.setNickname(one.getNickname());
                u.setRealName(one.getRealName());
                u.setPhone(one.getPhone());
                u.setPoints(one.getPoints());
                u.setEmail(one.getEmail());
                u.setAddress(one.getAddress());
                u.setStatus(one.getStatus());
                u.setComments(one.getComments());
                u.setCompanyId(one.getCompanyId());

                // 设置角色（如果提供）
                if (one.getRoleName() != null && !one.getRoleName().trim().isEmpty()) {
                    Role role = roleService.getOne(new QueryWrapper<Role>()
                            .eq("role_name", one.getRoleName()), false);
                    if (role != null) {
                        u.setRoles(Collections.singletonList(role));
                    }
                }

                // 设置机构（如果提供）
                if (one.getOrganizationName() != null && !one.getOrganizationName().trim().isEmpty()) {
                    Organization organization = organizationService.getOne(new QueryWrapper<Organization>()
                            .eq("organization_full_name", one.getOrganizationName()), false);
                    if (organization != null) {
                        u.setOrganizationId(organization.getOrganizationId());
                    }
                }

                // 设置性别（如果提供）
                if (one.getSexName() != null && !one.getSexName().trim().isEmpty()) {
                    DictionaryData sex = dictionaryDataService.getByDictCodeAndName("sex", one.getSexName());
                    if (sex != null) {
                        u.setSex(sex.getDictDataCode());
                    }
                }

                // 关键修复：将用户添加到列表中
                users.add(u);
            }

            // 保存新用户（逐个保存以处理角色关系）
            int successCount = 0;
            List<String> failedUsers = new ArrayList<>();
            List<User> successUsers = new ArrayList<>();

            for (User user : users) {
                try {
                    // 先保存用户基本信息
                    if (userService.save(user)) {
                        // 如果有角色，再保存角色关系
                        if (user.getRoles() != null && !user.getRoles().isEmpty()) {
                            List<Integer> roleIds = user.getRoles().stream()
                                    .map(Role::getRoleId)
                                    .collect(Collectors.toList());
                            userRoleService.saveBatch(user.getUserId(), roleIds);
                        }
                        successCount++;
                        successUsers.add(user);
                    } else {
                        failedUsers.add(user.getUsername());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    failedUsers.add(user.getUsername());
                    // 继续处理下一个用户，不中断整个导入过程
                }
            }

            // 同步成功导入的用户到 websopy
            for (User successUser : successUsers) {
                userSyncService.syncUserToWebsopy(successUser);
            }

            // 构建返回消息
            StringBuilder message = new StringBuilder();
            if (successCount > 0) {
                message.append("成功导入").append(successCount).append("个用户");
            }
            if (!skippedUsers.isEmpty()) {
                if (message.length() > 0) {
                    message.append("，");
                }
                message.append("跳过").append(skippedUsers.size()).append("个已存在用户");
            }
            if (!failedUsers.isEmpty()) {
                if (message.length() > 0) {
                    message.append("，");
                }
                message.append("失败").append(failedUsers.size()).append("个用户");
            }
            if (message.length() == 0) {
                message.append("没有新用户需要导入");
            }

            // 构建返回数据
            Map<String, Object> resultData = new HashMap<>();
            if (!skippedUsers.isEmpty()) {
                resultData.put("skipped", skippedUsers);
            }
            if (!failedUsers.isEmpty()) {
                resultData.put("failed", failedUsers);
            }

            // 返回结果
            return success(message.toString(), resultData.isEmpty() ? null : resultData);
        } catch (Exception e) {
            e.printStackTrace();
            return fail("导入失败：" + e.getMessage(), null);
        }
    }

    /**
     * 下载用户导入模板
     */
    @Operation(summary = "下载用户导入模板")
    @GetMapping("/import/template")
    public void downloadImportTemplate(HttpServletResponse response) {
        try {
            // 创建示例数据
            List<UserImportParam> templateData = new ArrayList<>();

            // 添加示例数据行
            UserImportParam example1 = new UserImportParam();
            example1.setUsername("admin001");
            example1.setPassword("123456");
            example1.setNickname("管理员");
            example1.setRealName("张三");
            example1.setPhone("13800138001");
            example1.setPoints(1000);
            example1.setEmail("admin@example.com");
            example1.setOrganizationName("总公司");
            example1.setSexName("男");
            example1.setRoleName("管理员");
            example1.setStatus(0);
            example1.setAddress("地址");
            example1.setComments("");
            templateData.add(example1);

            UserImportParam example2 = new UserImportParam();
            example2.setUsername("user001");
            example2.setPassword("123456");
            example2.setNickname("注册用户");
            example2.setRealName("李四");
            example2.setPhone("13800138002");
            example1.setPoints(2000);
            example2.setEmail("user@example.com");
            example2.setOrganizationName("分公司");
            example2.setSexName("女");
            example2.setRoleName("注册用户");
            example1.setStatus(0);
            example2.setAddress("地址");
            example2.setComments("");
            templateData.add(example2);

            // 设置导出参数
            ExportParams exportParams = new ExportParams("用户导入模板", "用户数据");
            exportParams.setCreateHeadRows(true);

            // 生成Excel工作簿
            Workbook workbook = ExcelExportUtil.exportExcel(exportParams, UserImportParam.class, templateData);

            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            String fileName = "用户导入模板.xlsx";
            response.setHeader("Content-Disposition", "attachment; filename=\"" +
                java.net.URLEncoder.encode(fileName, "UTF-8") + "\"");

            // 输出到响应流
            workbook.write(response.getOutputStream());
            workbook.close();

        } catch (Exception e) {
            e.printStackTrace();
            try {
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write("{\"code\":1,\"message\":\"模板下载失败：" + e.getMessage() + "\"}");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    @PreAuthorize("hasAuthority('sys:auth:user')")
    @PostMapping("/getAvatarByMpWx")
    @Operation(summary = "更新微信头像")
    public ApiResult<?> getAvatarByMpWx(@RequestBody User user) {
        user.setAvatar("https://oa.gxwebsoft.com/assets/logo.7ccfefb9.svg");
        if (userService.updateUser(user)) {
            return success("更新成功");
        }
        return fail("更新失败");
    }

    @PostMapping("/updatePointsBySign")
    @Operation(summary = "签到成功累加积分")
    public ApiResult<?> updatePointsBySign() {
        final User loginUser = getLoginUser();
        loginUser.setPoints(loginUser.getPoints() + 1);
        if (userService.updateUser(loginUser)) {
            return success("签到成功");
        }
        return fail("签到失败");
    }

    @PreAuthorize("hasAuthority('sys:auth:user')")
    @PutMapping("/updateUserBalance")
    @Operation(summary = "更新用户余额")
    public ApiResult<?> updateUserBalance(@RequestBody User user) {
        if (getLoginUser() == null) {
            return fail("请先登录");
        }
        if (userService.updateUser(user)) {
            return success("操作成功");
        }
        return fail("操作失败");
    }

    @PostMapping("/updateUserBalanceWithoutLogin")
    @Operation(summary = "更新用户余额(无需登陆)")
    public ApiResult<?> updateUserBalanceWithoutLogin(@RequestBody User user) {
        if (user.getAuthCode() == null || !user.getAuthCode().equals("1700083"))
            return fail("参数错误");
        if (userService.updateById(user)) {
            return success("操作成功");
        }
        return fail("操作失败");
    }

    @PostMapping("/addUserBalanceWithoutLogin")
    @Operation(summary = "增加用户余额(无需登陆)")
    public ApiResult<?> addUserBalanceWithoutLogin(@RequestBody User user) {
        if (user.getAuthCode() == null || !user.getAuthCode().equals("1700083"))
            return fail("参数错误");
        User user1 = userService.getByIdRel(user.getUserId());
        user1.setBalance(user1.getBalance().add(user.getBalance()));
        if (userService.updateById(user1)) {
            return success("操作成功");
        }
        return fail("操作失败");
    }

    @PostMapping("/updateUserOfficeOpenidWithoutLogin")
    @Operation(summary = "更新用户公众号openid(无需登陆)")
    public ApiResult<?> updateUserOfficeOpenidWithoutLogin(@RequestBody User user) {
        if (user.getAuthCode() == null || !user.getAuthCode().equals("1700083"))
            return fail("参数错误");
        if (userService.updateUser(user)) {
            return success("操作成功");
        }
        return fail("操作失败");
    }

    @Operation(summary = "获取用户(无需登陆)")
    @PostMapping("/getUserWithoutLogin")
    public ApiResult<?> getUserWithoutLogin(@RequestBody User user) {
        if (user.getAuthCode() == null || !user.getAuthCode().equals("1700083"))
            return fail("参数错误");
        return success(userService.getByIdRel(user.getUserId()));
    }

    @PreAuthorize("hasAuthority('sys:user:list')")
    @OperationLog
    @Operation(summary = "统计用户余额")
    @GetMapping("/countUserBalance")
    public ApiResult<?> countUserBalance(User param) {
        final LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.gt(User::getBalance, 0);
        if (!param.getOrganizationId().equals(0)) {
            wrapper.eq(User::getOrganizationId, param.getOrganizationId());
        }
        final List<User> list = userService.list(wrapper);
        final BigDecimal totalBalance = list.stream().map(User::getBalance).reduce(BigDecimal.ZERO, BigDecimal::add);
        //      System.out.println("统计用户余额 = " + totalBalance);
        return success("统计成功", totalBalance);
    }

    @Operation(summary = "更新商户ID")
    @PutMapping("/updateUserMerchantId")
    public ApiResult<?> updateUserMerchantId(@RequestBody User user) {
        if (userService.updateUser(user)) {
            return success("更新成功");
        }
        return fail("更新失败");
    }

    @Operation(summary = "园区内用户数")
    @GetMapping("/userNumInPark")
    public ApiResult<?> userNumInPark(UserParam param) {
        return success("统计成功", userService.userNumInPark(param));
    }

    @Operation(summary = "园区内企业数")
    @GetMapping("/orgNumInPark")
    public ApiResult<?> orgNumInPark(UserParam param) {
        return success("统计成功", userService.orgNumInPark(param));
    }

    @PreAuthorize("hasAuthority('sys:auth:user')")
    @Operation(summary = "查询全部用户")
    @GetMapping("/listAdminsByPhoneAll")
    public ApiResult<?> listAdminsByPhoneAll(LoginParam param, HttpServletRequest request){
      final List<User> adminsByPhone = userService.getAdminsByPhone(param);
      if (adminsByPhone.size() == 1) {
        // 设置过期时间
        Long tokenExpireTime = configProperties.getTokenExpireTime();
        final User user = adminsByPhone.get(0);
        // 签发token
        String access_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), user.getTenantId()),
          tokenExpireTime, configProperties.getTokenKey());
        loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_LOGIN, null, user.getTenantId(), request);
        return success("登录成功", new LoginResult(access_token, user));
      }
      return success(adminsByPhone);
    }

    @PreAuthorize("hasAuthority('sys:user:pageAll')")
    @Operation(summary = "查询全部用户All")
    @GetMapping("/pageAll")
    public ApiResult<List<User>> pageAll(UserParam param){
      final User loginUser = getLoginUser();
      if(loginUser != null){
        if(!loginUser.getTenantId().equals(5)){
          param.setTenantId(getLoginUser().getTenantId());
        }
      }
      return success(userService.pageAll(param));
    }
}
