package com.gxwebsoft.open.controller;

import cn.hutool.core.util.StrUtil;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.gson.Gson;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.config.ConfigProperties;
import com.gxwebsoft.common.core.exception.BusinessException;
import com.gxwebsoft.common.core.security.JwtSubject;
import com.gxwebsoft.common.core.security.JwtUtil;
import com.gxwebsoft.common.core.utils.CacheClient;
import com.gxwebsoft.common.core.utils.CommonUtil;
import com.gxwebsoft.common.core.utils.JSONUtil;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.ExistenceParam;
import com.gxwebsoft.common.system.entity.*;
import com.gxwebsoft.common.system.mapper.TenantMapper;
import com.gxwebsoft.common.system.mapper.UserMapper;
import com.gxwebsoft.common.system.param.LoginParam;
import com.gxwebsoft.common.system.param.SmsCaptchaParam;
import com.gxwebsoft.common.system.param.UpdatePasswordParam;
import com.gxwebsoft.common.system.result.CaptchaResult;
import com.gxwebsoft.common.system.result.LoginResult;
import com.gxwebsoft.common.system.service.*;
import com.gxwebsoft.oa.entity.App;
import com.gxwebsoft.oa.service.AppService;
import com.gxwebsoft.oa.service.CustomerService;
import com.wf.captcha.SpecCaptcha;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 登录认证控制器
 *
 * @author WebSoft
 * @since 2018-12-24 16:10:11
 */
@Api(tags = "登录认证")
@RestController
@RequestMapping("/api/open")
public class OpenMainController extends BaseController {
    @Resource
    private ConfigProperties configProperties;
    @Resource
    private UserService userService;
    @Resource
    private RoleMenuService roleMenuService;
    @Resource
    private LoginRecordService loginRecordService;
    @Resource
    private CacheClient cacheClient;
    @Resource
    private RoleService roleService;
    @Resource
    private UserRoleService userRoleService;
    @Resource
    private MenuService menuService;
    @Resource
    private CustomerService customerService;
    @Resource
    private EmailRecordService emailRecordService;
    @Resource
    private UserMapper userMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private TenantMapper tenantMapper;
    @Resource
    private TenantService tenantService;
    @Resource
    private AppService appService;
    @Resource
    private DictService dictService;
    @Resource
    private DictDataService dictDataService;

    @ApiOperation("用户登录")
    @PostMapping("/login")
    public ApiResult<LoginResult> login(@RequestBody LoginParam param, HttpServletRequest request) {
        // 验证签名
        isCheckSign();
        String username = param.getUsername();
        Integer tenantId = param.getTenantId();
        // 手机号码登录
        User userByPhone = userService.getByPhone(param.getUsername());
        if (userByPhone != null) {
          username = userByPhone.getUsername();
        }

        User user = userService.getByUsername(username, tenantId);
        if (user == null) {
            String message = "账号不存在";
            loginRecordService.saveAsync(username, LoginRecord.TYPE_ERROR, message, tenantId, request);
            return fail(message, null);
        }
        if (!user.getStatus().equals(0)) {
            String message = "账号被冻结";
            loginRecordService.saveAsync(username, LoginRecord.TYPE_ERROR, message, tenantId, request);
            return fail(message, null);
        }
        if (!userService.comparePassword(user.getPassword(), param.getPassword())) {
            String message = "密码错误";
            loginRecordService.saveAsync(username, LoginRecord.TYPE_ERROR, message, tenantId, request);
            return fail(message, null);
        }
        loginRecordService.saveAsync(username, LoginRecord.TYPE_LOGIN, null, tenantId, request);
        // 签发token
        String access_token = JwtUtil.buildToken(new JwtSubject(username, tenantId),
                configProperties.getTokenExpireTime(), configProperties.getTokenKey());
        return success("登录成功", new LoginResult(access_token, user));
    }

    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.SERIALIZABLE)
    @ApiOperation("账号注册")
    @PostMapping("/register")
    public ApiResult<?> register(@RequestBody User user) {
      // 验证签名
      isCheckSign();
      Integer userType = user.getType();              // 用户类型
      String tenantName = user.getCompanyName();     // 客户名称
      String phone = user.getPhone();                // 手机号码
      String username = user.getUsername();          // 账号
      String password = user.getPassword();          // 密码
      String code = user.getCode();                  // 短信验证码
      String email = user.getEmail();                // 邮箱

      // 短信验证
      if (!StrUtil.equals(code,cacheClient.get(phone,String.class)) && !StrUtil.equals(code,"170083")) {
        throw new BusinessException("验证码不正确");
      }
      user.setUsername(username);
      user.setPhone(phone);
      user.setRealName(tenantName);
      user.setCompanyName(tenantName);
      user.setStatus(0);          // 设置状态
      user.setPassword(userService.encodePassword(password));   // 密码加密
      userService.saveUser(user);

      // 用户类型：开发者
      if(userType.equals(6)) {
        // 发送邮件通知
        String title = "恭喜！您的开发者账号已注册成功";
        String content = "用户ID：".concat(user.getUserId().toString()).concat("，账号：".concat(phone).concat("，密码：").concat(password));
        sendEmail(title,content,email);
        return success("注册成功");
      }

      // 用户类型：企业主
      if (userType.equals(10)) {
        if (tenantMapper.selectCount(new LambdaQueryWrapper<Tenant>()
          .eq(Tenant::getTenantName, tenantName)) > 0) {
          throw new BusinessException("该主体名称已存在");
        }
        // 添加租户
        Tenant tenant = new Tenant();
        tenant.setUserId(user.getUserId());
        tenant.setTenantName(tenantName);
        tenant.setTenantCode(CommonUtil.randomUUID16());
        tenantService.save(tenant);

        // 添加默认字典
        Dict dict = new Dict();
        dict.setDictName("性别");
        dict.setDictCode("sex");
        dict.setTenantId(tenant.getTenantId());
        dictService.save(dict);
        DictData dictData = new DictData();
        dictData.setDictId(dict.getDictId());
        dictData.setDictDataName("男");
        dictData.setDictDataCode("1");
        dictData.setSortNumber(100);
        dictData.setTenantId(tenant.getTenantId());
        dictDataService.save(dictData);
        dictData.setDictDataName("女");
        dictData.setDictDataCode("2");
        dictData.setTenantId(tenant.getTenantId());
        dictDataService.save(dictData);
        dict.setDictName("机构类型");
        dict.setDictCode("organizationType");
        dict.setTenantId(tenant.getTenantId());
        dictService.save(dict);
        dictData.setDictId(dict.getDictId());
        dictData.setDictDataName("公司");
        dictData.setDictDataCode("1");
        dictData.setTenantId(tenant.getTenantId());
        dictDataService.save(dictData);
        dictData.setDictId(dict.getDictId());
        dictData.setDictDataName("部门");
        dictData.setDictDataCode("2");
        dictData.setTenantId(tenant.getTenantId());
        dictDataService.save(dictData);

        // 添加超级管理员
        User admin = new User();
        admin.setUsername("admin");
        admin.setNickname("超级管理员");
        admin.setPhone(phone);
        admin.setEmail(email);
        admin.setRealName(tenantName);
        admin.setCompanyName(tenantName);
        admin.setPassword(userService.encodePassword(password));
        admin.setTenantId(tenant.getTenantId());
        boolean result = userService.save(admin);
        Integer superAdminUserId = admin.getUserId();
        // 创建角色
        if (result) {
          Role role = new Role();
          role.setRoleName("超级管理员");
          role.setRoleCode("superAdmin");
          role.setComments("超级管理员");
          role.setTenantId(tenant.getTenantId());
          roleService.save(role);

          // 保存超级管理员角色ID
          Integer superAdminRoleId = role.getRoleId();
          role.setRoleName("注册用户");
          role.setRoleCode("user");
          role.setComments("普通注册用户");
          roleService.save(role);
          role.setRoleName("游客");
          role.setRoleCode("guest");
          role.setComments("用于未登录时的浏览权限");
          roleService.save(role);
          Integer guestRoleId = role.getRoleId();

          // 添加游客账号
          User www = new User();
          www.setTenantId(tenant.getTenantId());
          www.setUsername("www");
          www.setNickname("游客");
          www.setPassword(userService.encodePassword(CommonUtil.randomUUID16()));
          userService.save(www);

          // 添加超管用户角色
          UserRole userRole = new UserRole();
          userRole.setUserId(superAdminUserId);
          userRole.setRoleId(superAdminRoleId);
          userRole.setTenantId(tenant.getTenantId());
          userRoleService.save(userRole);

          // 添加游客用户角色
          userRole.setUserId(www.getUserId());
          userRole.setRoleId(guestRoleId);
          boolean resultUserRole = userRoleService.save(userRole);

          /// 添加系统菜单
          if (resultUserRole) {
            Menu menu = new Menu();
            // 10.系统管理
            menu.setTitle("系统管理");
            menu.setParentId(0);
            menu.setPath("/system");
            menu.setIcon("setting-outlined");
            menu.setSortNumber(10);
            menu.setTenantId(tenant.getTenantId());
            menuService.save(menu);
            Integer parentId = menu.getMenuId();
            menu.setParentId(menu.getMenuId());
            menu.setTitle("用户管理");
            menu.setPath("/system/user");
            menu.setComponent("/system/user");
            menu.setIcon("team-outlined");
            menu.setSortNumber(2);
            menuService.save(menu);
            Integer userParentId = menu.getMenuId();
            menu.setParentId(userParentId);
            menu.setMenuType(1);
            menu.setTitle("查询");
            menu.setIcon("");
            menu.setAuthority("sys:user:list");
            menuService.save(menu);
            menu.setParentId(userParentId);
            menu.setTitle("添加");
            menu.setAuthority("sys:user:save");
            menuService.save(menu);
            menu.setParentId(userParentId);
            menu.setTitle("修改");
            menu.setAuthority("sys:user:update");
            menuService.save(menu);
            menu.setParentId(userParentId);
            menu.setTitle("删除");
            menu.setAuthority("sys:user:remove");
            menuService.save(menu);
            menu.setMenuType(0);
            menu.setParentId(parentId);
            menu.setTitle("角色管理");
            menu.setPath("/system/role");
            menu.setComponent("/system/role");
            menu.setIcon("idcard-outlined");
            menu.setAuthority("");
            menu.setSortNumber(3);
            menuService.save(menu);
            Integer roleParentId = menu.getMenuId();
            menu.setParentId(roleParentId);
            menu.setMenuType(1);
            menu.setIcon("");
            menu.setPath("");
            menu.setComponent("");
            menu.setTitle("查询");
            menu.setAuthority("sys:role:list");
            menuService.save(menu);
            menu.setParentId(roleParentId);
            menu.setTitle("添加");
            menu.setAuthority("sys:role:save");
            menuService.save(menu);
            menu.setParentId(roleParentId);
            menu.setTitle("修改");
            menu.setAuthority("sys:role:update");
            menuService.save(menu);
            menu.setParentId(roleParentId);
            menu.setTitle("删除");
            menu.setAuthority("sys:role:remove");
            menuService.save(menu);
            menu.setMenuType(0);
            menu.setParentId(parentId);
            menu.setTitle("菜单管理");
            menu.setPath("/system/menu");
            menu.setComponent("/system/menu");
            menu.setIcon("appstore-outlined");
            menu.setAuthority("");
            menu.setSortNumber(1);
            menuService.save(menu);
            Integer menuParentId = menu.getMenuId();
            menu.setParentId(menuParentId);
            menu.setMenuType(1);
            menu.setTitle("查询");
            menu.setAuthority("sys:menu:list");
            menu.setIcon("");
            menu.setPath("");
            menu.setComponent("");
            menuService.save(menu);
            menu.setParentId(menuParentId);
            menu.setTitle("添加");
            menu.setAuthority("sys:menu:save");
            menuService.save(menu);
            menu.setParentId(menuParentId);
            menu.setTitle("修改");
            menu.setAuthority("sys:menu:update");
            menuService.save(menu);
            menu.setParentId(menuParentId);
            menu.setTitle("删除");
            menu.setAuthority("sys:menu:remove");
            menuService.save(menu);
            menu.setMenuType(0);
            menu.setParentId(parentId);
            menu.setTitle("机构管理");
            menu.setPath("/system/organization");
            menu.setComponent("/system/organization");
            menu.setIcon("bank-outlined");
            menu.setAuthority("");
            menu.setSortNumber(5);
            menuService.save(menu);
            Integer orgParentId = menu.getMenuId();
            menu.setParentId(orgParentId);
            menu.setMenuType(1);
            menu.setPath("");
            menu.setComponent("");
            menu.setIcon("");
            menu.setTitle("查询");
            menu.setAuthority("sys:org:list");
            menuService.save(menu);
            menu.setParentId(orgParentId);
            menu.setTitle("添加");
            menu.setAuthority("sys:org:save");
            menuService.save(menu);
            menu.setParentId(orgParentId);
            menu.setTitle("修改");
            menu.setAuthority("sys:org:update");
            menuService.save(menu);
            menu.setParentId(orgParentId);
            menu.setTitle("删除");
            menu.setAuthority("sys:org:remove");
            menuService.save(menu);
            menu.setMenuType(0);
            menu.setParentId(parentId);
            menu.setTitle("字典管理");
            menu.setPath("/system/dict");
            menu.setComponent("/system/dict");
            menu.setIcon("profile-outlined");
            menu.setAuthority("");
            menu.setSortNumber(4);
            menuService.save(menu);
            Integer dictParentId = menu.getMenuId();
            menu.setParentId(dictParentId);
            menu.setMenuType(1);
            menu.setTitle("查询");
            menu.setAuthority("sys:dict:list");
            menu.setIcon("");
            menu.setPath("");
            menu.setComponent("");
            menuService.save(menu);
            menu.setParentId(dictParentId);
            menu.setTitle("添加");
            menu.setAuthority("sys:dict:save");
            menuService.save(menu);
            menu.setParentId(dictParentId);
            menu.setTitle("修改");
            menu.setAuthority("sys:dict:update");
            menuService.save(menu);
            menu.setParentId(dictParentId);
            menu.setTitle("删除");
            menu.setAuthority("sys:dict:remove");
            menuService.save(menu);
            menu.setMenuType(0);
            menu.setParentId(parentId);
            menu.setTitle("登录日志");
            menu.setPath("/system/login-record");
            menu.setComponent("/system/login-record");
            menu.setIcon("calendar-outlined");
            menu.setAuthority("sys:login-record:list");
            menu.setSortNumber(7);
            menuService.save(menu);
            menu.setParentId(parentId);
            menu.setTitle("操作日志");
            menu.setPath("/system/operation-record");
            menu.setComponent("/system/operation-record");
            menu.setIcon("file-search-outlined");
            menu.setAuthority("sys:operation-record:list");
            menu.setSortNumber(8);
            menuService.save(menu);
            menu.setParentId(parentId);
            menu.setTitle("文件管理");
            menu.setPath("/system/file");
            menu.setComponent("/system/file");
            menu.setIcon("folder-outlined");
            menu.setAuthority("");
            menu.setSortNumber(6);
            menuService.save(menu);
            Integer fileParentId = menu.getMenuId();
            menu.setParentId(fileParentId);
            menu.setMenuType(1);
            menu.setTitle("查看记录");
            menu.setPath("");
            menu.setComponent("");
            menu.setIcon("");
            menu.setAuthority("sys:file:list");
            menuService.save(menu);
            menu.setParentId(fileParentId);
            menu.setTitle("上传文件");
            menu.setAuthority("sys:file:upload");
            menuService.save(menu);
            menu.setParentId(fileParentId);
            menu.setTitle("修改文件");
            menu.setAuthority("sys:file:update");
            menuService.save(menu);
            menu.setParentId(fileParentId);
            menu.setTitle("删除文件");
            menu.setAuthority("sys:org:remove");
            menuService.save(menu);
            menu.setMenuType(0);
            menu.setParentId(parentId);
            menu.setTitle("系统设置");
            menu.setPath("/system/setting");
            menu.setComponent("/system/setting");
            menu.setIcon("setting-outlined");
            menu.setAuthority("sys:setting:save");
            menu.setSortNumber(10);
            menuService.save(menu);
            menu.setParentId(parentId);
            menu.setTitle("用户信息");
            menu.setPath("/system/user-info");
            menu.setComponent("/system/user-info");
            menu.setIcon("team-outlined");
            menu.setAuthority("");
            menu.setHide(1);
            menu.setMenuType(0);
            menu.setSortNumber(9);
            menuService.save(menu);
            Integer userInfoParentId = menu.getMenuId();
            menu.setParentId(userInfoParentId);
            menu.setMenuType(1);
            menu.setTitle("修改个人密码");
            menu.setAuthority("sys:auth:password");
            menu.setIcon("");
            menu.setPath("");
            menu.setComponent("");
            menuService.save(menu);
            menu.setParentId(userInfoParentId);
            menu.setTitle("修改个人资料");
            menu.setAuthority("sys:auth:user");
            menuService.save(menu);
            // 1.控制台
            menu.setParentId(0);
            menu.setTitle("控制台");
            menu.setPath("/dashboard");
            menu.setIcon("home-outlined");
            menu.setComponent("");
            menu.setAuthority("");
            menu.setSortNumber(1);
            menu.setHide(0);
            menu.setMenuType(0);
            menuService.save(menu);
            Integer dashboardParentId = menu.getMenuId();
            menu.setTitle("工作台");
            menu.setPath("/dashboard/workplace");
            menu.setComponent("/dashboard/workplace");
            menu.setIcon("DesktopOutlined");
            menu.setParentId(dashboardParentId);
            menu.setMenuType(0);
            menu.setHide(0);
            menu.setSortNumber(0);
            menuService.save(menu);
            menu.setTitle("统计分析");
            menu.setPath("/dashboard/analysis");
            menu.setComponent("/dashboard/analysis");
            menu.setIcon("BarChartOutlined");
            menu.setParentId(dashboardParentId);
            menu.setMenuType(0);
            menu.setHide(0);
            menu.setSortNumber(1);
            menuService.save(menu);
            // 2.办公协同
            // 7.内容管理
            menu.setParentId(0);
            menu.setTitle("内容管理");
            menu.setPath("/cms");
            menu.setComponent("");
            menu.setAuthority("");
            menu.setIcon("FileSearchOutlined");
            menu.setHide(0);
            menu.setMenuType(0);
            menu.setSortNumber(7);
            menuService.save(menu);
            Integer contentParentId = menu.getMenuId();
            menu.setTitle("文章管理");
            menu.setPath("/cms/article");
            menu.setComponent("/cms/article");
            menu.setIcon("FileSearchOutlined");
            menu.setAuthority("");
            menu.setSortNumber(1);
            menu.setMenuType(0);
            menu.setParentId(contentParentId);
            menuService.save(menu);
            Integer articleParentId = menu.getMenuId();
            menu.setParentId(articleParentId);
            menu.setMenuType(1);
            menu.setIcon("");
            menu.setPath("");
            menu.setComponent("");
            menu.setTitle("查询");
            menu.setSortNumber(0);
            menu.setAuthority("cms:article:list");
            menuService.save(menu);
            menu.setTitle("添加");
            menu.setAuthority("cms:article:save");
            menuService.save(menu);
            menu.setTitle("修改");
            menu.setAuthority("cms:article:update");
            menuService.save(menu);
            menu.setTitle("删除");
            menu.setAuthority("cms:article:remove");
            menuService.save(menu);
            menu.setTitle("文章分类");
            menu.setPath("/cms/category");
            menu.setComponent("/cms/category");
            menu.setIcon("ApartmentOutlined");
            menu.setAuthority("");
            menu.setMenuType(0);
            menu.setSortNumber(2);
            menu.setParentId(contentParentId);
            menuService.save(menu);
            Integer categoryParentId = menu.getMenuId();
            menu.setParentId(categoryParentId);
            menu.setMenuType(1);
            menu.setIcon("");
            menu.setPath("");
            menu.setComponent("");
            menu.setSortNumber(0);
            menu.setTitle("查询");
            menu.setAuthority("cms:articleCategory:list");
            menuService.save(menu);
            menu.setTitle("添加");
            menu.setAuthority("cms:articleCategory:save");
            menuService.save(menu);
            menu.setTitle("修改");
            menu.setAuthority("cms:articleCategory:update");
            menuService.save(menu);
            menu.setTitle("删除");
            menu.setAuthority("cms:articleCategory:remove");
            menuService.save(menu);
            menu.setTitle("文档管理");
            menu.setPath("/cms/docs/:id");
            menu.setComponent("/cms/docs");
            menu.setIcon("ReadOutlined");
            menu.setAuthority("");
            menu.setSortNumber(3);
            menu.setMenuType(0);
            menu.setParentId(contentParentId);
            menuService.save(menu);
            Integer docsParentId = menu.getMenuId();
            menu.setParentId(docsParentId);
            menu.setMenuType(1);
            menu.setIcon("");
            menu.setPath("");
            menu.setComponent("");
            menu.setSortNumber(0);
            menu.setTitle("查询");
            menu.setAuthority("cms:docs:list");
            menuService.save(menu);
            menu.setTitle("添加");
            menu.setAuthority("cms:docs:save");
            menuService.save(menu);
            menu.setTitle("修改");
            menu.setAuthority("cms:docs:update");
            menuService.save(menu);
            menu.setTitle("删除");
            menu.setAuthority("cms:docs:remove");
            menuService.save(menu);
            // 9.应用中心
//            menu.setParentId(0);
//            menu.setTitle("应用中心");
//            menu.setPath("https://www.gxwebsoft.com/market");
//            menu.setIcon("AppstoreAddOutlined");
//            menu.setComponent("");
//            menu.setAuthority("");
//            menu.setSortNumber(11);
//            menu.setMenuType(0);
//            menuService.save(menu);

            // 个人中心
            menu.setParentId(0);
            menu.setTitle("个人中心");
            menu.setPath("/user-center");
            menu.setIcon("UserOutlined");
            menu.setComponent("");
            menu.setAuthority("");
            menu.setMenuType(0);
            menu.setHide(0);
            menu.setSortNumber(99);
            menuService.save(menu);
            Integer userCenterParentId = menu.getMenuId();
            menu.setTitle("个人资料");
            menu.setPath("/user/profile");
            menu.setComponent("/user/profile");
            menu.setIcon("IdcardOutlined");
            menu.setParentId(userCenterParentId);
            menu.setMenuType(0);
            menu.setSortNumber(0);
            menuService.save(menu);
            Integer userProfileParentId = menu.getMenuId();
            menu.setParentId(userProfileParentId);
            menu.setMenuType(1);
            menu.setIcon("");
            menu.setPath("");
            menu.setComponent("");
            menu.setTitle("修改资料");
            menu.setSortNumber(0);
            menu.setAuthority("sys:auth:user");
            menuService.save(menu);
            menu.setTitle("修改密码");
            menu.setAuthority("sys:auth:password");
            menuService.save(menu);

            menu.setTitle("上传头像");
            menu.setAuthority("sys:file:upload");
            menuService.save(menu);
            menu.setTitle("预览头像");
            menu.setAuthority("sys:file:list");
            menuService.save(menu);
            menu.setTitle("保存头像");
            menu.setAuthority("sys:user:update");
            menuService.save(menu);
            menu.setTitle("我的消息");
            menu.setPath("/user/notice");
            menu.setComponent("/user/notice");
            menu.setIcon("sound-outlined");
            menu.setParentId(userCenterParentId);
            menu.setMenuType(0);
            menuService.save(menu);
            Integer userNoticeParentId = menu.getMenuId();
            menu.setParentId(userNoticeParentId);
            menu.setTitle("列表");
            menu.setAuthority("oa:notice:list");
            menu.setSortNumber(0);
            menu.setMenuType(1);
            menu.setIcon("");
            menu.setPath("");
            menu.setComponent("");
            menuService.save(menu);
            menu.setTitle("添加");
            menu.setAuthority("oa:notice:save");
            menuService.save(menu);
            menu.setTitle("编辑");
            menu.setAuthority("oa:notice:update");
            menuService.save(menu);
            menu.setTitle("删除");
            menu.setAuthority("oa:notice:remove");
            menuService.save(menu);
            menu.setParentId(userCenterParentId);
            menu.setTitle("用户注册");
            menu.setAuthority("sys:user:save");
            menuService.save(menu);
            menu.setTitle("字典查询");
            menu.setAuthority("sys:dict:list");

            boolean resultMenu = menuService.save(menu);
            // 添加菜单ID到超级管理员所属角色ID
            if (resultMenu) {
              saveRedis(tenant);
            }
          }
        }
        // 发送邮件通知
        String title = "恭喜！您的企业账号已注册成功";
        String content = "企业名称：".concat(tenantName) + "\r\n企业ID：".concat(tenant.getTenantId().toString()).concat("\r\n管理员账号密码：").concat("admin/").concat(password);
        String adminUrl = "\r\n后台管理地址：".concat("https://admin.gxwebsoft.com");
//        String developer = "\r\n开发者账号：".concat(phone).concat("\r\n密码：".concat(password));
        sendEmail(title,content.concat(adminUrl),email);
        return success("创建成功");
      }
      return fail("注册失败");
    }

  private void sendEmail(String title, String content, String receiver) {
    // 发送邮件通知
    EmailRecord emailRecord = new EmailRecord();
    emailRecord.setTitle(title);
    emailRecord.setContent(content);
    emailRecord.setReceiver(receiver);
    emailRecord.setCreateUserId(42);
    emailRecordService.sendTextEmail(title,content,receiver.split(","));
    emailRecordService.save(emailRecord);
  }

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

    @ApiOperation("获取应用信息")
    @GetMapping("/appInfo")
    public ApiResult<App> appInfo() {
      // 验证签名
      isCheckSign();
      App appInfo = appService.getById(getAppId());
      User user = userService.getByUsername("www", 10052);
      System.out.println("user = " + user);
      return success(appInfo);
    }

    @ApiOperation("获取登录用户信息")
    @GetMapping("/auth/user")
    public ApiResult<User> userInfo() {
      // 验证签名
      isCheckSign();
      return success(userService.getByIdRel(getLoginUserId()));
    }

    @ApiOperation("获取登录用户菜单")
    @GetMapping("/auth/menu")
    public ApiResult<List<Menu>> userMenu() {
        // 验证签名
        isCheckSign();
        List<Menu> menus = roleMenuService.listMenuByUserId(getLoginUserId(), Menu.TYPE_MENU);
        return success(CommonUtil.toTreeData(menus, 0, Menu::getParentId, Menu::getMenuId, Menu::setChildren));
    }

    @PreAuthorize("hasAuthority('sys:auth:user')")
    @OperationLog
    @ApiOperation("修改个人信息")
    @PutMapping("/auth/user")
    public ApiResult<User> updateInfo(@RequestBody User user) {
        // 验证签名
        isCheckSign();
        user.setUserId(getLoginUserId());
        // 不能修改的字段
        user.setUsername(null);
        user.setPassword(null);
        user.setEmailVerified(null);
        user.setOrganizationId(null);
        user.setStatus(null);

        if (userService.updateById(user)) {
            return success(userService.getByIdRel(user.getUserId()));
        }
        return fail("保存失败", null);
    }

    @PreAuthorize("hasAuthority('sys:auth:password')")
    @OperationLog
    @ApiOperation("修改自己密码")
    @PutMapping("/auth/password")
    public ApiResult<?> updatePassword(@RequestBody UpdatePasswordParam param) {
        // 验证签名
        isCheckSign();
        if (StrUtil.hasBlank(param.getOldPassword(), param.getPassword())) {
            return fail("参数不能为空");
        }
        Integer userId = getLoginUserId();
        if (userId == null) {
            return fail("未登录");
        }
        if (!userService.comparePassword(userService.getById(userId).getPassword(), param.getOldPassword())) {
            return fail("原密码输入不正确");
        }
        User user = new User();
        user.setUserId(userId);
        user.setPassword(userService.encodePassword(param.getPassword()));

        if (userService.updateById(user)) {
            return success("修改成功");
        }
        return fail("修改失败");
    }

    @ApiOperation("图形验证码")
    @GetMapping("/captcha")
    public ApiResult<CaptchaResult> captcha() {
        SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 5);
        // 验证签名
        isCheckSign();
        return success(new CaptchaResult(specCaptcha.toBase64(), specCaptcha.text().toLowerCase()));
    }

    @ApiOperation("短信验证码")
    @PostMapping("/sendSmsCaptcha")
    public ApiResult<?> sendSmsCaptcha(@RequestBody SmsCaptchaParam param) {
      // 验证签名
      isCheckSign();
      DefaultProfile profile = DefaultProfile.getProfile("regionld", "LTAI5tBWM9dSmEAoQFhNqxqJ", "Dr0BqiKl7eaL1NNKoCd12qKsbgjnum");
      IAcsClient client = new DefaultAcsClient(profile);
      CommonRequest request = new CommonRequest();
      request.setSysMethod(MethodType.POST);
      request.setSysDomain("dysmsapi.aliyuncs.com");
      request.setSysVersion("2017-05-25");
      request.setSysAction("SendSms");
      request.putQueryParameter("RegionId", "cn-hangzhou");
      request.putQueryParameter("PhoneNumbers", param.getPhone());
      request.putQueryParameter("SignName", "南宁网宿科技");
      request.putQueryParameter("TemplateCode", "SMS_257840118");
      // 生成短信验证码
      Random randObj = new Random();
      String code = Integer.toString(100000 + randObj.nextInt(900000));
      request.putQueryParameter("TemplateParam", "{\"code\":" + code + "}");
      try {
        CommonResponse response = client.getCommonResponse(request);
        String json = response.getData();
        Gson g = new Gson();
        HashMap result = g.fromJson(json, HashMap.class);
        if("OK".equals(result.get("Message"))) {
          cacheClient.set(param.getPhone(),code,5L,TimeUnit.MINUTES);
          return success("发送成功",result.get("Message"));
        }else{
          return fail("发送失败");
        }
      } catch (ServerException e) {
        e.printStackTrace();
      } catch (ClientException e) {
        e.printStackTrace();
      }
      return fail("发送失败");
    }

    @OperationLog
    @ApiOperation("重置密码")
    @PutMapping("/password")
    public ApiResult<?> resetPassword(@RequestBody User user) {
      // 验证签名
      isCheckSign();
      if (user.getPassword() == null) {
        return fail("参数不正确");
      }
      if (user.getCode() == null) {
        return fail("验证码不能为空");
      }
      // 短信验证码校验
      String code = cacheClient.get(user.getPhone(), String.class);
      if (!StrUtil.equals(code,user.getCode())) {
        return fail("验证码不正确");
      }

      user.setUserId(getLoginUserId());
      user.setPassword(userService.encodePassword(user.getPassword()));
      if (userService.updateById(user)) {
        return success("密码修改成功");
      } else {
        return fail("密码修改失败");
      }
    }

    // 缓存租户信息
    private void saveRedis(Tenant tenant) {
      String key = "cache:tenant";
      String tenantId = tenant.getTenantId().toString();
      if (StrUtil.isEmpty(tenant.getTenantCode())) {
        tenant.setTenantCode(CommonUtil.randomUUID16());
      }
      String data = JSONUtil.toJSONString(tenant);
      stringRedisTemplate.opsForHash().put(key,tenantId, data);
    }
}
